简体   繁体   English

Rails回形针和多个文件上传

[英]Rails Paperclip & Multiple File Uploads

I am looking for a solution to give the user the ability to upload multiple images through one file_field. 我正在寻找一种解决方案,让用户能够通过一个file_field上传多个图像。 I have looked in to options such a Jquery File Upload and Uploadify but have yet to come across good examples with a working solution. 我已经查看了诸如Jquery File Upload和Uploadify之类的选项,但是还没有找到一个有效工作解决方案的例子。

I already have multiple images setup, 我已经有多个图像设置,

 has_attached_file :asset,
                   :styles => { :large => "640x480", :medium => "300x300", :thumb => "100x100" },
                   :storage => :s3,
                   :s3_credentials => "#{Rails.root}/config/s3.yml",
                   :path => "/:contributor_id/:listing_name/:filename"

Right now I am displaying 5 individual file_fields 现在我正在显示5个单独的file_fields

def new
  @listing = Listing.new
  5.times {@listing.assets.build }

  respond_to do |format|
    format.html # new.html.erb
    format.json { render json: @listing }
  end
end

I would like to have 我想拥有

<%= f.file_field :asset, :multiple => true %>

That allows the user to select multiple files in their file browser. 这允许用户在其文件浏览器中选择多个文件。 But how can I process these with a nested model? 但是如何使用嵌套模型处理这些? And get them to upload. 并让他们上传。

So there are a few issues here. 所以这里有一些问题。

First, Paperclip's has_attached_file method isn't an association to many files. 首先,Paperclip的has_attached_file方法不是许多文件的关联。 It looks like you're trying to build an "asset" as if it's a Rails association. 看起来你正试图建立一个“资产”,好像它是一个Rails协会。 All Paperclip does is put a couple of fields into your table to store some meta-data about the file and you get one attached file per declaration of has_attached_file . 所有Paperclip都会在您的表中放置几个​​字段来存储有关该文件的一些元数据,并且每个has_attached_file声明都会获得一个附加文件。 If you want to attach 5 files, you would need to do something like: 如果要附加5个文件,则需要执行以下操作:

has_attached_file :asset1
has_attached_file :asset2
has_attached_file :asset3
has_attached_file :asset4
has_attached_file :asset5

OR, alternatively, you could create another model just to store the files. 或者,您也可以创建另一个模型来存储文件。 For example: 例如:

class Listing < ActiveRecord::Base
  has_many :assets
end

class Asset < ActiveRecord::Base
  belongs_to :listing
  has_attached_file :picture
end

That way, you could have multiple assets attached to one listing (you didn't say what the original object was so I just called it "listing"). 这样,你可以将多个资产附加到一个列表中(你没有说原始对象是什么,所以我只称它为“列表”)。

Second, there is no such thing as a multiple file upload in HTML (and, as such, the file_field method doesn't take a :multiple => true argument. You'll have to use something beyond Rails built-in form handling if you want multiple-file upload. Uploadify is a decent choice (that I've used before). There is a gem that will transform file fields to use uploadify (and will support the :multiple => true syntax that you want): https://github.com/mateomurphy/uploadify_rails3/wiki . However, I cannot vouch for how good it is. 其次,HTML中没有多文件上传的东西(因此, file_field方法不会采用:multiple => true参数。除了Rails内置表单处理之外,你还必须使用其他东西。你想要多文件上传.Uploadify是一个不错的选择(我以前用过)。有一个gem将转换文件字段以使用uploadify(并将支持你想要的:multiple => true语法): https ://github.com/mateomurphy/uploadify_rails3/wiki 。但是,我不能保证它有多好。

My advice would be to start step-by-step. 我的建议是一步一步地开始。 Uploading via Flash to Rails can be a complicated process that involves dealing with the CSRF meta-tag and other fields in your form. 通过Flash上​​传到Rails可能是一个复杂的过程,涉及处理CSRF元标记和表单中的其他字段。 Start by making a form that allows a user to upload one file and stores it through Paperclip. 首先制作一个允许用户上传一个文件并通过Paperclip存储的表单。 Then maybe break the has_attached_file declaration into another model so that you can have 1 or many files associated with a model (as shown in the multi-model code block above). 然后可以将has_attached_file声明分解为另一个模型,这样就可以有1个或多个与模型关联的文件(如上面的多模型代码块所示)。 Then try adding Uploadify or another alternative. 然后尝试添加Uploadify或其他替代方案。 Ernie Miller has a decent tutorial on integrating Uploadify: http://erniemiller.org/2010/07/09/uploadify-and-rails-3/ . Ernie Miller有一个关于集成Uploadify的体面教程: http//erniemiller.org/2010/07/09/uploadify-and-rails-3/

To start, remember that has_attached_file can only attach one file. 首先,请记住has_attached_file只能附加一个文件。 When you try calling @listing.assets there is no "assets". 当你尝试调用@listing.assets ,没有“资产”。 There is an asset. 一种资产。 You need to create a separate model yourself and use Rails' associations if you want multiple files. 如果需要多个文件,您需要自己创建一个单独的模型并使用Rails的关联。

Accepted answer says there is no such thing as a multiple file upload in HTML. 接受的答案说,HTML中没有多文件上传。

<%= f.file_field :files, multiple: true %>

This allows you to select multiple images and send them as an array. 这允许您选择多个图像并将它们作为数组发送。

If you have the relationship Dog has_many Images and Image has_attachment :file , do this to get multiple images to upload at once: 如果你有关系Dog has_many ImagesImage has_attachment :file ,请执行此操作以立即上传多个图像:

In your html.erb 在你的html.erb中

<%= form_for @dog, html: { multipart: true } do |f| %>
  <%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %>
<%= end %>

In your controller 在你的控制器中

def dog_params
  params.require(:dog).permit files: []
end

In your Dog model 在你的狗模型

def files=(array = [])
  array.each do |f|
    images.create file: f
  end
end

This is assuming you're already able to upload one image but want to upgrade to multiple images at once. 这假设您已经能够上传一个图像但想要一次升级到多个图像。 Notice that wait time will increase. 请注意,等待时间会增加。

To help reduce wait time, peep my post on this question related to speed uploading. 为了减少等待时间,请在与速度上传相关的问题上查看我的帖子

Here is a full example of multiple file uploads. 以下是多个文件上传的完整示例。 Here a user has_many uploads . 这里有一个user has_many uploads Each upload model has an avatar which represents the file attachment. 每个upload模型都有一个代表文件附件的avatar Ultimately: we are creating many uploads when we create the user . 最终:我们在创建user时创建了许多uploads

The Models 模特

#models/user.rb
class User < ApplicationRecord
  has_many :uploads

  def files=(array_of_files = [])
    array_of_files.each do |f|
      uploads.build(avatar: f, user: self)
    end
  end
end


#models/upload.rb
class Upload < ApplicationRecord
  belongs_to :user

  has_attached_file :avatar
  validates_attachment_content_type :avatar, :content_type => ["image/png"]
end

The form: 表格:

# views/users/_form.html.erb
<%= form_with(model: user, local: true) do |form| %>

  ...

  <div class="field">
    <%= form.file_field :files, multiple: true %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

The Controller 控制器

class UsersController < ApplicationController
  before_action :set_user, only: [:show]

  def show
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to @user, notice: 'User was successfully created.'
    end
  end

  private
    def set_user
      @user = User.find(params[:id])
    end

    def user_params
      params.require(:user).permit(:name, files: [])
    end
end

User#show 用户#秀

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @user.name %>
</p>


<h3>Uploads</h3>
<div>
  <% @user.uploads.each do |upload|  %>
    <div>
      <%= link_to upload.avatar.url do%>
        <%= upload.avatar_file_name %>
      <% end %>
    </div>
  <% end %>
</div>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM