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
Rails Console: Reload! Not Reflecting Changes in Model Files? What Could Be Possible Reason
Converting String from Snake_Case to Camelcase in Ruby
How to Edit or Write on Existing Pdf With Ruby
Google Plus API Shutdown Today, Which Alternative Can Be Used to Authentication
Can't Install Rails on MAC Os Catalina
Ruby on Rails: Advanced Search
How to Have Class.Property = X Return Something Other Than X
Is There a Better Way of Checking Nil or Length == 0 of a String in Ruby
Invalid Active Developer Path on MAC Os X After Installing Ruby
Ruby on Rails Best Practices - Big Controller VS Small Controller
How to Hide Password Input from Terminal in Ruby Script
How to Convert Datetime.Now to Utc in Ruby
Convert Unicode Codepoint to String Character in Ruby
Ruby on Rails Callback, What Is Difference Between :Before_Save and :Before_Create