Uploading multiple files at once to Rails app with Carrierwave (HTML5)

11,189

Solution 1

You can do a little hack for the params array, something like:

aux = []
params[:gallery][:photos_attributes][:image].each do |f|
  aux << {:image => f}
end
params[:post][:photos_attributes] = aux

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

I have a similar problem, I know it's an ugly hack, but it works for me.

Solution 2

Ditch accepts_nested_attributes_for and instead add this to your Gallery model.

def photos=(attrs)
  attrs.each { |attr| self.photos.build(:image => attr) }
end

Also, make sure that photos is in your gallery's accessible attribs in case you're protecting against mass assignment. Otherwise you won't get the photos array hash assignment from your params. I.e.

attr_accessible :field1, field2, :photos
Share:
11,189
Meltemi
Author by

Meltemi

Updated on June 29, 2022

Comments

  • Meltemi
    Meltemi almost 2 years

    I'm close...very close...I'm able to upload single files just fine...but when i change the type of my form's file_field to :multiple => true so I can upload multiple images at once my uploaded files get wrapped in an array...and the 'magic' of 'accepts_nested_attributes_for` is lost.

    Edit: After more examination I wonder if I even need to bother with accepts_nested_attributes_for? Perhaps I should just have a file_field, :multiple => true in my Gallery form (as opposed to a nested form) and then in my create action create the new gallery and then loop through each element in the params[:gallery][:photos_attributes]["0"][:image] array by hand, so to speak, calling @gallery.photos.create for each element. ?!? Seems cumbersome...but it's all I can come up with.

    Hoping someone with more experience with Rails can chime in...

    Params:

    {"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
    

    GalleriesController

      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
    
  • Meltemi
    Meltemi almost 13 years
    i like this approach. but i need to assign the user_id from the session to each photo...and not sure how?...can't seem to get at session from within the model.