Oviron
Oviron

Reputation: 161

Rails 4 Multiple file upload using carrierwave and nested forms

I have a catalog item with many images and trying to upload all of it by one request using nested forms and carrierwave. I also use responders, haml and simple form. So, it's something like:

item.rb

class Item < ActiveRecord::Base
  has_many :images, dependent: :destroy
  accepts_nested_attributes_for :images
end

image.rb

class Image < ActiveRecord::Base
  belongs_to :item
  mount_uploader :image, ImageUploader
end

_form.html.haml

= simple_form_for(@item, :html => {:multipart => true }) do |f|
  = f.error_notification

  .form-inputs
    = f.input :name
    = f.input :description
    = f.input :price

  = simple_fields_for :images do |image|
    = image.file_field :image, multiple: true

  .form-actions
    = f.button :submit

items_controller.rb

...
def new
  @item = Item.new
  respond_with(@item)
end

def create
  @item = Item.new(item_params)
  @item.save
  respond_with(@item)
end
...
def item_params
  params.require(:item).permit(
    :name, :description, :price,
    image_attributes: [:image]
  )
end

I'm new to rails and it's obviously not working the way i want it to. It saves item and completely ignore all images.

So, i'm wondering, is there any way to achieve my goal without constructions like

def create
  @item = Item.new(item_params)
  params[:images].each do |image|
    img = Image.new
    img.image = image
    @item.images << img
  end
  @item.save
  respond_with(@item)
end

Upvotes: 3

Views: 2761

Answers (2)

Oviron
Oviron

Reputation: 161

So, finally i found the answer. There was some mistakes in my html form. The first mistake was pretty much obvious. I used

= simple_fields_for :images do |image|

instead of

= f.simple_fields_for :images do |image|

in _form.html.haml The second one i found after reading this article. So i changed my nested form to this:

= f.simple_fields_for :images, Image.new do |image_form|
    = image_form.file_field :image, multiple: true,
                   name: "item[images_attributes][][image]"

And as Pavan advised, used images_attributes in pluralized form in my items_controller.rb:

def item_params
  params.require(:item).permit(
    :name, :description, :price,
    images_attributes: [:image]
  )
end

And thats all.

Upvotes: 5

Pavan
Pavan

Reputation: 33542

Try changing your new method to like below

def new
  @item = Item.new
  @item.images.build
  respond_with(@item)
end

Also, as you are uploading multiple images, change your item_params to below

def item_params
  params.require(:item).permit(:name, :description, :price, images_attributes: [:image => []])
end

Upvotes: 0

Related Questions