Erihon1890
Erihon1890

Reputation: 45

How validate <%= file_field_tag "images[]", type: :file, multiple: true %>

I have a two model

Gallery

class Gallery < ActiveRecord::Base
    has_many :pictures, :dependent => :destroy

    accepts_nested_attributes_for :pictures, :allow_destroy => true

    attr_accessible :name, :description, :pictures_attributes

    validates_presence_of :pictures
end

Picture

    class Picture < ActiveRecord::Base
      belongs_to :gallery

      has_attached_file :image,
        :path => ":rails_root/public/images/:id/:filename",
        :url  => "/images/:id/:filename"
    end

And form

    <%= form_for @gallery, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
    .........
     <div class="controls">
          <%= file_field_tag "images[]", type: :file, multiple: true %>
        </div>
    .........
    <% end %>

Controller

    def create
        @gallery = Gallery.new(gallery_params)

        respond_to do |format|
          if @gallery.save

            if params[:images]         
              params[:images].each { |image|
                @gallery.pictures.create(image: image)
              }
            end

            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
private

  def gallery_params
    params.require(:gallery).permit(:description,
                                    :name,
                                    :pictures
                                   )
  end

If I want to validate has_many pictures image blank?, I got every time a error that Pictures is blank, even I selected images.

How I validate has_many association with multiple image field?

Params

 Parameters: {"utf8"=>"✓", "authenticity_token"=>"MCkZFvsYvRndlfaqwXiw5MfhSHGoesawEAPFWzn0Ulw=", "gallery"=>{"name"=>"", "description"=>""}, "images"=>[#<ActionDispatch::Http::UploadedFile:0x007fb7ad9cb7d0 @tempfile=#<Tempfile:/var/folders/r4/jqx7vz8d48z2ky3ndpyzv9vc0000gn/T/RackMultipart20150926-38180-1xrchqg>, @original_filename="yamaha-blaster-BOARD-HEROa.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"images[]\"; filename=\"yamaha-blaster-BOARD-HEROa.jpg\"\r\nContent-Type: image/jpeg\r\n">], "commit"=>"Create Gallery"}
   (0.1ms)  begin transaction
   (0.0ms)  rollback transaction

Upvotes: 1

Views: 1073

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

Your problem lies in your use of accepts_nested_attributes_for - your model reference is to pictures whilst you're referring to images in your code.

Here's how you should do it:

#app/models/picture.rb
class Picture < ActiveRecord::Base
   belongs_to :gallery
   validates :image, presence: true

   has_attached_file :image,
        :path => ":rails_root/public/images/:id/:filename",
        :url  => "/images/:id/:filename"
end

#app/models/gallery.rb
class Gallery < ActiveRecord::Base
   has_many :pictures
   accepts_nested_attributes_for :pictures, allow_destroy: true
end

You're getting confused about the image object and the Picture model. IE you need to pass the images to the Picture model through your Gallery model:

#app/controllers/galleries_controller.rb
class GalleriesController < ApplicationController
   def new
      @gallery = Gallery.new
      @gallery.pictures.build
   end

   def create
      @gallery = Gallery.new gallery_params
      @gallery.save
   end

   private

   def gallery_params
      params.require(:gallery).permit(:description, :name, pictures_attributes: [:images])
   end
end

This means you're going to have to use f.fields_for, which can be tricky.

Here's how to do it:

#app/views/galleries/new.html.erb
<%= form_for @gallery do |f| %>
   <%= f.text_field :name %>
   <%= f.fields_for :pictures do |picture| %>
      <%= picture.file_field type: :file, multiple: true %>
   <% end %>
   <%= f.submit %>
<% end %>

This should work for you. The multiple aspect of the upload, I am not sure about.

Upvotes: 1

Related Questions