The structure of our app is the following: A Gallery has many Pictures. Each Picture has one image, which is the paperclip attachment.


Lets start with the Gallery model

# app/models/gallery.rb
class Gallery < ActiveRecord::Base

  has_many :pictures, :dependent => :destroy

In app/views/galleries/_form.html.erb we set up the form to create a new gallery. Use HTML5 multiple attribute to enable multiple file selection. On submit all selected files are returned to the gallery controller as an array "images[]", ready for paperclip!!

file_field_tag is used since images is not a @gallery attribute.

<!-- app/views/galleries/_form.html.erb -->
<%= form_for @gallery, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
  <div class="control-group">
    <%= f.label :name, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :name, :class => 'text_field' %>
  <div class="control-group">
    <%= f.label :description, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :description, :class => 'text_field' %>

  <div class="control-group">
    <%= f.label :pictures, :class => 'control-label' %>
    <div class="controls">
      <!-- The magic is coming ...look at my eyes....shazammmm -->
      <!-- Use HTML5 multiple attribute to enable multiple selection
           and pass back to controller all files as an array, ready 
           for paperclip!!
           file_field_tag, since images is not a gallery attribute
      <%= file_field_tag "images[]", type: :file, multiple: true %>

  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                galleries_path, :class => 'btn btn-mini' %>
<% end %>

Line 25 shows the magic :P

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

In app/controllers/galleries_controller.rb#create, gallery is saved first and then all images. Thus, there is no need to keep any unnecessary tokens, hashes…etc, just to give a gallery_id in pictures new entries.

# app/controllers/galleries_controller.rb
def create
  @gallery = Gallery.new(gallery_params)

  respond_to do |format|
    if @gallery.save
      if params[:images]
        #===== The magic is here ;)
        params[:images].each { |image|
          @gallery.pictures.create(image: image)

      format.html { redirect_to @gallery, notice: 'Gallery was successfully created.' }
      format.json { render json: @gallery, status: :created, location: @gallery }
      format.html { render action: "new" }
      format.json { render json: @gallery.errors, status: :unprocessable_entity }


Just for the record, below you can check the Picture model.

# app/models/picture.rb
class Picture < ActiveRecord::Base
  belongs_to :gallery

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

  do_not_validate_attachment_file_type :image

Demo app

Clone the demo application if you want to play with the source. In a following post, I will try to add validation and preview of the files before upload, like jquery-file-upload plugin.