Multiple File Uploads With Paperclip (Screencast)
Paperclip is a really great gem/plugin for Ruby on Rails that makes handling file attachments super easy. If your new to paperclip I would highly recommend taking a look at the following resources before getting started:
While Paperclip is great when working on projects that require only one file attachment, things can get a little tricky when you need to work with multiple files. This makes something that should be easy, say, a Photo Album that has_many attachments hard to setup if you've never done it before.
Setup and Configuration
# config/environment.rb gem.config "paperclip" # Install the Gem rake gems:install # Generate the "Asset" Model ruby script/generate model Asset article_id:integer # Add the required Paperclip columns to our Asset model ruby script/generate migration AddPaperclipToAssets image_file_name:string image_content_type:string image_file_size:integer # Tell Paperclip where to find your ImageMagick installation (not always required) # development.rb Paperclip.options[:image_magick_path] = '/path/to/your/image_magick'
Setup the Models
# app/models/asset.rb belongs_to :article has_attached_file :image, :styles => { :thumb=> "100x100#", :small => "300x300>", :large => "600x600>" } # app/models/article.rb has_many :assets, :dependent => :destroy accepts_nested_attributes_for :assets, allow destroy => true
Setup the Controllers
# apps/controllers/articles_controller.rb def new @article = Article.new() 5.times { @article.assets.build } end def edit @article = Article.find(params[:id]) 5.times { @article.assets.build } end
Setup the Form Partial
# apps/views/articles/_form.html.erb # Make sure your form is multipart with :html => { :multipart => true } <div class="newPaperclipFiles"> <%= f.fields_for :assets do |asset| %> <% if asset.object.new_record? %> <%= asset.file_field :image %> <% end %> <% end %> </div> <div class="existingPaperclipFiles"> <% f.fields_for :assets do |asset| %> <% unless asset.object.new_record? %> <div class="thumbnail"> <%= link_to( image_tag(asset.object.image.url(:thumb)), asset.object.image.url(:original) ) %> <%= asset.check_box :_delete %> </div> <% end %> <% end %> </div>
-
Gregg Turnbull
9:13 PM on Friday, August 13th, 2010
Just a few updates needed to make it work on my end:
in _form.html.erb added to form tag ", :html => { :multipart => true }"
{ :multipart => true } do |f| %>and in # app/models/asset.rb added ",allow destroy=>true"
accepts_nested_attributes_for :recharge_assets, :allow_destroy => trueAfter that all worked dandy... thanks for the post.
-
Emerson Lackey
5:04 PM on Monday, August 16th, 2010
Thanks Gregg,
Added the relevant changes to the post. -
Allen
8:41 AM on Thursday, August 19th, 2010
Thinking about if asset model is polymorphic, how could it be? or asset model belongs_to user model, where should we add user association
-
oscar
9:14 AM on Friday, August 27th, 2010
Thanks for the sreencast!
Please, can you attach the rails project?
It would be fantastic to see the video, look the code and do some experiments. -
mulox
3:39 PM on Friday, August 27th, 2010
Very good screencast! i just see it and it's very useful.
Please, do another screencast teaching how to add javascript to delete the images, or the button to add an image field dynamically.
(any hope to see the code or your blog?)Thanks
-
gerard
8:34 AM on Monday, August 30th, 2010
Thanks for the screencast, it's very useful.
Can you do another explaining how to do last steps of the screencasts? all the stuff with ajax...
Is released the code of your blog? i'm interested in how you resolve the problem of create dynamically all the attachments that you want... -
Pierre-Alain Bandinelli
10:12 AM on Sunday, September 26th, 2010
Hello Emerson,
Very good post. But a few things to change for Rails 3 :In # config/environment.rb
gem.config "paperclip" must become
gem "paperclip"To install the Gem
rake gems:install must become
bundle installIn the view _form.html.erb,
must becomeIn the model article.rb,
accepts_nested_attributes_for :assets, allow destroy => true
must become
accepts_nested_attributes_for :assets, :allow_destroy => trueI hope it will help !
Thanks again for the post -
Pierre-Alain Bandinelli
10:14 AM on Sunday, September 26th, 2010
Obviously sthg went wrong with my previous post :
In the view _form.html.erb, the :_delete must be replaced with :_destroy
"" must become "" -
Pierre-Alain Bandinelli
10:15 AM on Sunday, September 26th, 2010
Once again sorry, I've just understood that the posts do not allow ruby code starting with <%
So
asset.check_box :_delete
must become
asset.check_box :_destroy -
Stan
8:44 AM on Tuesday, October 5th, 2010
Thanks a lot for the podcast! Exactly what I was looking for.
-
Matenia Rossides
2:10 PM on Monday, November 1st, 2010
Hi, Fantastic Screen Cast,
I have implemented this many times over to date, and still love the approach.
I have one query that is completely doing my head in at the moment.
I want to render the existing thumbnails on the edit page but need to order them by their position attribute. Is there a way to do fields_for and sort by position not id?
Hope there's someone out there that has had this problem and has a workaround / solution :)Kind Regards,
Matenia -
Susi
2:12 PM on Tuesday, November 9th, 2010
This works under rails 3.0 too! Great work.
How do you display uploaded images? Can you put this in your tut? That would make your tut perfect. Many people would be glad. Thanks
-
John
5:48 PM on Tuesday, December 7th, 2010
Thanks for the tutorial. I just set this up with Rails 3 and it worked great.
-
Mikael Jansson
12:37 PM on Monday, December 20th, 2010
asset.check_box :_delete
What if I want that to be a link under the thumb that says Destroy or Remove or something. -
Mikael Jansson
10:48 AM on Tuesday, December 21st, 2010
"asset.check_box :_delete
What if I want that to be a link under the thumb that says Destroy or Remove or something."Figured it out.
-
Stephan van Eijkelenburg
6:46 PM on Thursday, December 23rd, 2010
Thanks for the article, helped me a lot.
I think I might have found a solution to the 'now knowing how many files you want to attach upfront' problem mentioned at the end of the screencast.
Instead of using 'fields_for' you could use:
true %>This way you can upload many photos in modern browsers. For older / crappy browsers it's possible to insert " true %>" multiple times. Adding them with JQuery is also an option.
This worked for me in rails 3, not tested it in older versions
I hope this helps someone :)
-
Stephan van Eijkelenburg
3:33 AM on Friday, December 24th, 2010
Whoops, I see that my code got escaped / not displayed, sorry. Next try:
Instead of using 'fields_for' you could use:
file_field_tag 'article[assets_attributes][][image]', :multiple => trueThis way you can upload many photos in modern browsers. For older / crappy browsers it's possible to insert "file_field_tag 'article[assets_attributes][][image]', :multiple => true" multiple times. Adding them with JQuery is also an option.
This worked for me in rails 3, not tested it in older versions
I hope this helps someone :)
-
Raymond
10:14 PM on Tuesday, January 11th, 2011
Hey. Great tutorial.
I'm wanting to limit the amount of upload fields in the Edit view based on how many assets there already are in an article, so that an article will never under any circumstance end up with more than 5 assets.
So in the Edit action of the Articles controller I changed:
5.times { @article.assets.build }
to
(5 - @article.assets.length).times { @article.assets.build }
And I seem to get the right amount of upload fields based on how many assets already exist, but my question is, is this the best way to accomplish this? Bulletproof way of assuring there's never more than 5 assets per article and all?
Thanks for any response.
-
mike
11:33 AM on Wednesday, January 26th, 2011
Hello,
Would the source code for this screencast happen to be available somewhere for download?
-
Frank Thomas
8:11 AM on Thursday, February 3rd, 2011
Hi, I'm getting "ActionDispatch::Http::UploadedFile" inside my photos_attributes params. Anyone, know why this would happen? Thanks for the help!
-
modocache
9:01 AM on Saturday, February 5th, 2011
thanks a lot, this was really helpful. got it working on ror 3.0.3 / paperclip 2.3.8 with only minor adjustments:
articles_path, :html => { :multipart => true } ) do |f| %>
awesome resource, thanks.
-
Norm
4:49 AM on Monday, February 7th, 2011
Thanks for this!
I'm new to rails and this really helped with a project I'm working on. -
Alir3z4
1:54 AM on Friday, February 25th, 2011
tnx a ton!
i like carrierWave.
and i try this with carrierwave instead paperclip. -
Uriel
6:39 PM on Wednesday, March 2nd, 2011
What if i'm trying to upload multiple files to different models? How can I do the polymorphic association?
-
Mike
4:01 PM on Wednesday, April 13th, 2011
I've a name attribute and added the attr_accessible to it in the app/models/article.rb file:
attr_accessible :nameAfter that it didn't allow me to save the images. Using rails 3.0.5. Anyone encountered this?
-
Wijnand
11:08 AM on Wednesday, April 27th, 2011
Awesome... works perfectly.
Thanks for sharing : ) -
Bob
10:09 AM on Thursday, October 13th, 2011
And how can I upload unlimited files per one upload?
-
iotriado
10:31 PM on Sunday, December 18th, 2011
i use rails 3.0.11. When i try to save a new object with a nested paperclip photo at first it is not saved (obj.save = false). When i saved it without select a photo the object is created and stored to the database as well. when i edit the object and add a photo to it the object is saved successfully and the photo is upload too. Did anyone knows whats going on?
-
Lev
11:58 AM on Wednesday, December 28th, 2011
Maybe smb have already commented it, but anyway:
Here is some useful moments (tested on ruby 1.9.3, rails 3.1.3):
1. you should have installed ImageMagick
2. in article view in '' write '' instead of ''. Or you won't see the form with uploaded images.
3. in Article model add attr_accessible :assets_attributes . This will help you to done with some warnings. -
Frank
3:53 AM on Friday, January 6th, 2012
how would you display the images in the show view?
-
Jorge Giraldo
5:51 PM on Thursday, January 19th, 2012
Thanks, this is a great post. However, what if you don't know how many images you're going to upload? I mean, can the controller have a variable that depends on the images you want to upload, so that you don't need to have a fixed number of them?
-
Kleber
9:23 PM on Tuesday, February 28th, 2012
Thanks for posting this article! Very helpful !
In this case how do you test using Rspec?
-
Fernando
11:11 AM on Tuesday, April 24th, 2012
Congratz for the excelent screencast.
I followed all steps, but I'm still getting the errorCan't mass-assign protected attributes: asset
Even with the attr_accessible :content, :title, :assets_attributes on post.rb model
I'm using paperclip 3.0.2, rails 3.2.3 and ruby 1.9.3. Maybe something changed in paperclip/rails after this screencast was recorded.
-
gordon
3:43 PM on Sunday, May 6th, 2012
i think this was article was last updated in 2010 before rails 3.
May be a good idea to put a disclaimer at the top. -
Britt
4:26 PM on Friday, May 11th, 2012
Said before, but important. You must add:
# in the 'article.rb' model
attr_accessible :assets_attributesthis will silently fail and drive you nuts if you forget that
-
Crhistian
12:14 AM on Thursday, October 11th, 2012
how I can display the images on show?
I would appreciate your support, thanks
-
Lakeisha
8:32 AM on Thursday, December 20th, 2012
My brother suggested I would possibly like this blog.
He was once entirely right. This put up actually made my day.
You can not consider just how a lot time I had spent for
this info! Thanks! -
Kumar
9:08 AM on Thursday, December 27th, 2012
In case we are parsing data from the file which we are uploading (multiple files too) and filling up rows in the database. In that case each Article model (if I carry on with your example) should have multiple entries from the individual asset file and therefore we need to provide asset ID to the Article model. So...
Is it also possible to have a reverse association in contrast to what you have explained in the screencast i.e. asset would have "has_many :articles" and Article "belongs_to :asset"????? Will paperclip work fine in this case???