使用Carrierwave(HTML5)一次上传多个文件到Rails应用程序

7
我接近了……非常接近……我可以成功上传单个文件……但是当我把我的表单中的file_field类型更改为:multiple => true,这样我就可以一次上传多个图像,我的上传文件被包装在一个数组中……而“accepts_nested_attributes_for”的“魔力”就丢失了。

编辑: 经过更多的检查,我想知道是否需要费心去处理accepts_nested_attributes_for?也许我应该在我的Gallery表单中只有一个file_field, :multiple => true(而不是嵌套表单),然后在我的创建操作中手动循环遍历params[:gallery][:photos_attributes]["0"][:image]数组中的每个元素,逐个调用@gallery.photos.create。好像很繁琐……但这是我能想到的。

希望有更多Rails经验的人能发表意见……

参数:

{"utf8"=>"✓", 
"authenticity_token"=>"9jXvIwcllct7UyUfo6cvhEucQf2u3SY50SuaCLtFO4c=", 
"gallery"=>{
  "name"=>"First Gallery", 
  "photos_attributes"=>{"0"=>{
    "image"=>[
      #<ActionDispatch::Http::UploadedFile:0x00000104b78978 
        @original_filename="first_test_image.jpg", 
        @content_type="image/jpeg", 
        @headers="Content-Disposition: form-data; name=\"gallery[photos_attributes][0][image][]\"; filename=\"first_test_image.jpg\"\r\nContent-Type: image/jpeg\r\n", 
        @tempfile=#<File:/var/folders/bQ/bQYZC2ukFZCvbKzEDGRtJE+++TI/-Tmp-/RackMultipart20110622-4459-vz78ee>>, 
      #<ActionDispatch::Http::UploadedFile:0x00000104b78950 
        @original_filename="second_test_image.jpg", 
        @content_type="image/jpeg", 
        @headers="Content-Disposition: form-data; name=\"gallery[photos_attributes][0][image][]\"; filename=\"second_test_image.jpg\"\r\nContent-Type: image/jpeg\r\n", 
        @tempfile=#<File:/var/folders/bQ/bQYZC2ukFZCvbKzEDGRtJE+++TI/-Tmp-/RackMultipart20110622-4459-1jzhhyg>>
      ]
    }
  }
}, "commit"=>"Save", "action"=>"create", "controller"=>"galleries"}



#app/models/gallery.rb 
class Gallery < ActiveRecord::Base 
  has_many :photos, :dependent => :destroy 
  accepts_nested_attributes_for :photos 
end 

#app/models/photo.rb 
class Photo < ActiveRecord::Base 
  belongs_to :gallery 
  mount_uploader :photo, PhotoUploader 
end 

#config/routes.rb
resources :galleries do
  resources :photo, :only => [:create, :destroy]
end

图库控制器

  def new
    @gallery = Gallery.new
    @gallery.photos.build

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

  ...

  def create
    @gallery = Gallery.new(params[:gallery])

    respond_to do |format|
      if @gallery.save
        format.html { redirect_to @gallery, notice: 'Gallery was successfully created.' }
        format.json { render json: @gallery, status: :created, location: @gallery }
      else
        format.html { render action: "new" }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

2
只是出于好奇,"utf8"=>"✓" 是什么意思?为什么要打勾? - Matti Virkkunen
4
当你向服务器发送请求告诉它你使用的字符串编码时,默认情况下会将该信息传递给参数(params)。检查一下你的Rails服务器输出,你就能看到它了。 - iwasrobbed
1
@iWasRobbed:我其实并不使用Rails,只是对它感到好奇。谢谢你的解释! - Matti Virkkunen
你最终找到解决方案了吗? - M dunbavan
2个回答

4
您可以对params数组进行一些小技巧,类似于:
aux = []
params[:gallery][:photos_attributes][:image].each do |f|
  aux << {:image => f}
end
params[:post][:photos_attributes] = aux

@gallery = Gallery.new(params[:gallery])

我有类似的问题,虽然它看起来很丑陋,但对我很有效。


2
放弃使用accepts_nested_attributes_for,转而在你的Gallery模型中添加以下内容。
def photos=(attrs)
  attrs.each { |attr| self.photos.build(:image => attr) }
end

另外,请确保在防止大规模分配的情况下,照片在您的图库可访问属性中。否则,您将无法从参数中获得照片数组哈希分配。例如:

attr_accessible :field1, field2, :photos

我喜欢这种方法。但是我需要将“用户ID”从“会话”分配给每个照片...不确定如何做?...似乎无法从模型内部访问“会话”。 - Meltemi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接