我正在寻找一种解决方案,让用户能够通过一个file_field上传多个图像。我已经查看了诸如Jquery File Upload和Uploadify之类的选项,但是还没有找到一个有效工作解决方案的例子。
我已经设置了多个图像,
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"
现在我正在显示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
我想
<%= f.file_field :asset, :multiple => true %>
这允许用户在其文件浏览器中选择多个文件。但是如何使用嵌套模型处理这些?让他们上传。
答案 0 :(得分:35)
所以这里有一些问题。
首先,Paperclip的has_attached_file
方法不是许多文件的关联。看起来你正试图建立一个“资产”,好像它是一个Rails协会。所有Paperclip都会在您的表中放置几个字段来存储有关该文件的一些元数据,并且每个has_attached_file
声明都会获得一个附加文件。如果要附加5个文件,则需要执行以下操作:
has_attached_file :asset1
has_attached_file :asset2
has_attached_file :asset3
has_attached_file :asset4
has_attached_file :asset5
或者,您也可以创建另一个模型来存储文件。例如:
class Listing < ActiveRecord::Base
has_many :assets
end
class Asset < ActiveRecord::Base
belongs_to :listing
has_attached_file :picture
end
这样,您可以将多个资产附加到一个列表中(您没有说出原始对象是什么,所以我只是将其称为“列表”)。
其次,HTML中没有多文件上传(因此,file_field
方法不会采用:multiple => true
参数。你必须使用超出的东西如果你想要多文件上传,Rails内置表单处理.Uploadify是一个不错的选择(我以前用过)。有一个gem将转换文件字段以使用uploadify(并将支持:multiple => true
你想要的语法):https://github.com/mateomurphy/uploadify_rails3/wiki。但是,我不能保证它有多好。
我的建议是一步一步地开始。通过Flash上传到Rails可能是一个复杂的过程,涉及处理CSRF元标记和表单中的其他字段。首先制作一个允许用户上传一个文件并通过Paperclip存储的表单。然后可能将has_attached_file
声明分解为另一个模型,以便您可以拥有与模型关联的1个或多个文件(如上面的多模型代码块所示)。然后尝试添加Uploadify或其他替代方案。 Ernie Miller有一个关于集成Uploadify的合适教程:http://erniemiller.org/2010/07/09/uploadify-and-rails-3/。
首先,请记住has_attached_file
只能附加一个文件。当您尝试拨打@listing.assets
时,没有“资产”。有 资产。如果需要多个文件,您需要自己创建一个单独的模型并使用Rails的关联。
答案 1 :(得分:3)
接受的答案说,HTML中没有多文件上传的内容。
<%= f.file_field :files, multiple: true %>
这允许您选择多个图像并将它们作为数组发送。
如果您有关系Dog has_many Images
和Image has_attachment :file
,请执行此操作以立即上传多张图片:
在你的html.erb
中<%= form_for @dog, html: { multipart: true } do |f| %>
<%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %>
<%= end %>
在您的控制器中
def dog_params
params.require(:dog).permit files: []
end
在你的狗模型中
def files=(array = [])
array.each do |f|
images.create file: f
end
end
这假设您已经能够上传一张图片但想要一次升级到多张图片。请注意,等待时间会增加。
为了减少等待时间,请在与速度上传相关的问题上窥视 post 。
答案 2 :(得分:0)
这里是上传多个文件的完整示例。这里是var review_stars;
$("#send_review").click(function (e) {
$("fieldset input").click(function () {
var radios = document.getElementsByName('rating');
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
// do whatever you want with the checked radio
review_stars = radios[i].value;
// only one radio can be logically checked, don't check the rest
break;
}
}
});
。每个user has_many uploads
模型都有一个upload
,代表文件附件。最终:我们在创建avatar
时会创建许多uploads
。
模型
user
表单:
#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
控制器
# 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 %>
用户#show
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