The Ruby On Rails Paperclip Plugin Tutorial – Easy Image Attachments
I used Paperclip for my latest project, and I figured I would give a brief tutorial on how to use it.
Paperclip – Paperclip is intended as an easy file attachment library for ActiveRecord. The intent behind it was to keep setup as easy as possible and to treat files as much like other attributes as possible. http://github.com/thoughtbot/paperclip/tree/master
In my case, I wanted to allow an attachment to an Event, which will have one photo.
To install:
script/plugin install git://github.com/thoughtbot/paperclip.git |
Create your migration, again in my case I was adding the images to my Events model / DB, so I did the following:
script/generate migration AddPhotosToEvents |
Open up your newly created migration with your favorite Text editor, and add the following:
class AddPhotoToEvent < ActiveRecord::Migration def self.up add_column :events, :photo_file_name, :string add_column :events, :photo_content_type, :string add_column :events, :photo_file_size, :integer end def self.down remove_column :events, :photo_file_name remove_column :events, :photo_content_type remove_column :events, :photo_file_size end end |
Then rake your migration so the new columns are added to your database:
rake db:migrate |
Next you need to tell your model to use Paperclip, again I am using the Event model as an example, the #Paperclip and below is what you need to add. If you notice below I added 4 options to the :styles. I wanted to have a few different sizes generated when a image was uploaded, i named them appropriately (you can name them whatever you wish). Please note when you put a # on the end it signifies that you want that exact aspect ratio, it will crop your photo automatically. When you use > on the end it will make the largest side the size you specify and keep the aspect ratio uploaded. In addition note that because we specified has_attached_file :photo its going to look for that naming convention we created in the migration above. In addition it uses that name to store your photo in the public folder of your application. So our photo url is going to be as follows: /public/photos/(event#)/(size_name)/image_name
class Event < ActiveRecord::Base belongs_to :user validates_presence_of :title, :on => :create, :message => "can't be blank" validates_presence_of :teaser, :on => :create, :message => "can't be blank" validates_presence_of :subject, :on => :create, :message => "can't be blank" # Paperclip has_attached_file :photo, :styles => { :thumb=> "100x100#", :small => "150x150>", :medium => "300x300>", :large => "400x400>" } |
Next you need to make sure you put the html => { :multipart => true } in both your edit and new views for the model you are working with. Example in my case:
<% form_for(@event,:html => { :multipart => true }) do |f| %> <%= f.error_messages %> <%= render :partial => 'form', :locals => { :f => f } %> <% end %> |
You then need to add the file_field to your new and edit forms or your _form partial like in my case:
<p> <%= f.label 'Photo' %><br /> <%= f.file_field :photo %> </p> |
Next up is deciding on how you are going to use / view your images. In my case I wanted to show a few different sizes in the Event view. I also wanted to make sure I am only going to show photo’s if one exists. In this example I am just showing the small and medium sizes we generated:
<% if @event.photo.exists? then %> <p>Small:<%= image_tag @event.photo.url(:small) %></p> <p>Medium:<%= image_tag @event.photo.url(:medium) %></p> <% else %> <p> There are no photo's attached, upload one. </p> <% end %> |
A few other notes…
Calling @event.photo.nil destroys the photo
Also checkout this great tutorial Jim put up here.
Thats all for now, I’ll try to post an update with some more options / features when using the Paperclip plugin in the future.
*** Checkout my other tutorial on polymorphic paperclip if you would like to have multiple image attachments.
John Burmeister
Fixed a typo, it should be script/plugin install, not script/install to install paperclip
John Burmeister
Also, working on a polymorphic paperclip tutorial now, should be posted by tonight! Which allows multiple (unlimited) attachments per model.
Gustavo Gonzalez
Hello, I just want to say that first you need to install ImageMagick and rb-rmagick ports to get this going, that works in my case, thanks
SH
The line
add_column :events, :photo_updated_at, :datetime
has to be added in the migration file. The corresponding remove column has to added in the down method.
Ronen
Thanks for this great tutorial John.
For some reason I had a very difficult time installing the plugin. It would always start installing and then remove it right away. Eventually, I got it to work just by installing the gem for paperclip. I am using rails 2.1.2 and using gem version 1.3.1
‘gem install paperclip’
it installed version 2.1.2 and I was then able to generate my paperclip migration.
Just wanted to share that.
Thanks!
Ryan
Instead of typing out all of that code for the migration you can use
then rake the DB as usual.
As for the model, you can add some extra spice by setting the path/urls for the storage (very useful if your using subdomain assets). You can also set a default picture with the default_url which removes the “missing” text and replaces it with an image.
– Ryan
Ryan
sorry, there was a typo… it should be
for this example.
David
I thought I was on FaceBook for a second….
David G
I also had trouble with the plugin. it left an empty “paperclip” folder in my plugins dir.
“gem install paperclip” did the trick
Aaron Cohen
In some cases you’d want to pass the :style of photo into the exists?() method since some transformed versions of the original photo might not have been produced during upload.
e.g.
Small:
Medium:
John Burmeister
I need to update this tutorial… Gems are the way to go.
joe McGlynn
Not to nitpick, but this is image scaling, not cropping. I’m looking for an example of cropping (cut out a rectangular portion of an image).
KT
What if the files aren’t image files? I see the attributes in the migration are all image-related… is this only for image files?
Rick
I am getting ‘undefined method `photo’ for nil:NilClass’
Any ideas ????
Thanks
Jones Lee
Thanks for the tutorial, very clear and intuitive.
RiPr
Thanks! Worked for me!