Uploading Multiple Files With Paperclip

Rails Paperclip & Multiple File Uploads

So there are a few issues here.

First, Paperclip's has_attached_file method isn't an association to many files. It looks like you're trying to build an "asset" as if it's a Rails association. All Paperclip does is put a couple of fields into your table to store some meta-data about the file and you get one attached file per declaration of has_attached_file. If you want to attach 5 files, you would need to do something like:

has_attached_file :asset1
has_attached_file :asset2
has_attached_file :asset3
has_attached_file :asset4
has_attached_file :asset5

OR, alternatively, you could create another model just to store the files. For example:

class Listing < ActiveRecord::Base
has_many :assets
end

class Asset < ActiveRecord::Base
belongs_to :listing
has_attached_file :picture
end

That way, you could have multiple assets attached to one listing (you didn't say what the original object was so I just called it "listing").

Second, there is no such thing as a multiple file upload in HTML (and, as such, the file_field method doesn't take a :multiple => true argument. You'll have to use something beyond Rails built-in form handling if you want multiple-file upload. Uploadify is a decent choice (that I've used before). There is a gem that will transform file fields to use uploadify (and will support the :multiple => true syntax that you want): https://github.com/mateomurphy/uploadify_rails3/wiki. However, I cannot vouch for how good it is.

My advice would be to start step-by-step. Uploading via Flash to Rails can be a complicated process that involves dealing with the CSRF meta-tag and other fields in your form. Start by making a form that allows a user to upload one file and stores it through Paperclip. Then maybe break the has_attached_file declaration into another model so that you can have 1 or many files associated with a model (as shown in the multi-model code block above). Then try adding Uploadify or another alternative. Ernie Miller has a decent tutorial on integrating Uploadify: http://erniemiller.org/2010/07/09/uploadify-and-rails-3/.

To start, remember that has_attached_file can only attach one file. When you try calling @listing.assets there is no "assets". There is an asset. You need to create a separate model yourself and use Rails' associations if you want multiple files.

Rails 4 multiple file attachments with Paperclip

To save multiple files in the above example you, do not need add multiple: true option, it will cause an error when saving, one file - one record assets table.

For resolve this, you can add multiple file fields, like this:
add into controller:

def new
@project = Project.new
3.times{ @project.assets.build }
end

def edit
3.times{ @project.assets.build }
end

for while list

.permit(..., assets_attributes: [ :_destroy, :id, :image ])

and in view like this:

= f.simple_fields_for :assets do |a|
.small-1.columns
= a.label :image, :class => "left inline"
- if a.object.new_record?
.small-11.columns
= a.file_field :image
- else
.small-11.columns
= image_tag a.object.image.url(:thumb)
= a.input_field '_destroy', as: :boolean

If you try to send multiple images like this:

# view
a.file_field :image, multiple: true

# controller
.permit(..., assets_attributes: [ :_destroy, :id, image: [] ])

This will cause an error because the Asset model does not know what to do with an array of images.

To save more than one file at the same time, you need to use your own handler, for example:

model: add the images= method

def images=(files = [])
assets.create(image: f)
end

controller: move images: [] outside of the assets_attributes

.permit(..., images: [], assets_attributes: [ :_destroy, :id ])

view: remove the fields_for and nested attributes

  .row
.small-1.columns
=f.file_field :images, multiple: true
.row
= f.simple_fields_for :assets do |a|
.small-1.columns
= a.label :image, :class => "left inline"
....

How to Upload Multiple Image in Rails 4 Using Paperclip

Here is the article, which explains in details, how to achieve it.
Some code snippets from there are below.

Models:

# app/models/market.rb
class Market < ActiveRecord::Base
has_many :pictures, dependent: :destroy
end

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

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

do_not_validate_attachment_file_type :image
end

View:

# app/views/markets/_form.html.erb
<%= form_for @market, html: { class: "form-horizontal", multipart: true } do |f| %>
<div class="control-group">
<%= f.label :pictures, class: "control-label" %>
<div class="controls">
<%= file_field_tag "images[]", type: :file, multiple: true %>
</div>
</div>

<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" %>
</div>
<% end %>

Controller:

# app/controllers/markets_controller.rb
def create
@market = Market.new(market_params)

respond_to do |format|
if @market.save

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

format.html { redirect_to @market, notice: "Market was successfully created." }
format.json { render json: @market, status: :created, location: @market }
else
format.html { render action: "new" }
format.json { render json: @market.errors, status: :unprocessable_entity }
end
end
end

How to upload multiple files rails API

Change field name like pictures[] upload multiple images there.

At controller side

params[:pictures].each do  |picture|
Model.create(picture: picture)
end

How to setup paperclip to upload multiple files to s3

I got it working!
I changed the model to the following and it started working again! I must have edited it at some point and put the wrong name after has_attached_file.

class Asset < ActiveRecord::Base
belongs_to :project

has_attached_file :asset,
styles: {
large: '640x480#',
medium: '300x300>',
thumb: '100x100#'
},
:path => ':class/:id/:style.:extension'

end


Related Topics



Leave a reply



Submit