Paperclip Tips and Updates

Jon Yurek

So there’s been a bit of activity on the Paperclip front. I’ve added Amazon S3 support using the RightAWS gem. Some fellow githubbers have contributed some patches to fix up said S3 support, as well as to add more (and better) validations for content type, etc. We’ve brought it up to a nice, round v2.1.2 as of yesterday. Give yourselves a round of applause.

I highly encourage you to give it a whirl if you haven’t already. It’s very easy to both get and to use!

An interesting note!

Ken Robertson has gone to great lengths to port Paperclip to DataMapper, which should be great news for all you Merbers out there. He’s kept it quite up-to-date, and it’s right alongside the 2.1.2 current release. Hopefully we’ll be able to merge codebases in the future, though right now there’s enough of a difference between DM and AR to make that not terribly feasible.

Here’s a handy tip!

One of the most frequently asked questions is how to use data from your instances in the path and/or URL. The answer is the interpolations hash, which is quite user-extensible. Let’s say you had a song that played in the background of each User’s profile (making this exercise purely hypothetical, of course), and you wanted its name to be the same as the User’s username.

One really good way of allowing this functionality would be to add the following to your config/initializers/paperclip.rb file:

Paperclip::Attachment.interpolations[:username] = proc do |attachment, style|
  # or whatever you've named your User's login/username/etc. attribute

The #instance method is the instance of the model that this attachment is attached to. You can access any of the model’s attributes, methods, associations, and so on from that object just like normal. Also note that you don’t have to name your interpolation the same thing as the attribute you’re interpolating (though it helps clarity).

Now you can add this to your :path and :url parameters like so:

class User < ActiveRecord::Base
  has_attached_file :song,
                    :path => ":rails_root/public/system/:attachment/:username.:extension",
                    :url  => "/:attachment/:username.:extension"

When you call #url or #path on your attachment, Paperclip will run through the interpolations hash, find strings that match its keys, and replace them with the return values of the procs. In this case, you’d produce a lovely url of /songs/jyurek.mp3

It’s a very easy way to add flexibility to your files’ names without having to modify any code yourself.

Another handy tip!

S3 support is now baked in! The updated has_attached_file call looks kinda like this one does:

class House < ActiveRecord::Base
  has_attached_file :blueprint,
                    :styles => { :thumbnail => "150x150" },
                    :path => ":attachment/:id/:style.:extension",
                    :storage => :s3,
                    :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
                    :bucket => "bucket-of-holding"

Please note the additional options, including:

  • :storage: Specify :s3 here to use S3. Strictly speaking you could specify :filesystem here if you’re using the filesystem, but it’s the default so don’t bother.
  • :s3_credentials: You should give this a Hash, a path to a file, or a File object. The File should contain a YAML-ized Hash, and the contents of the Hash should be the accesskeyid and secretaccesskey used to access your S3 account. You can also environment-space these inside the hash, just like your database.yml file.
  • :bucket: The name of the S3 bucket that will be holding your data.

Note that there’s no :url option. That’s because the S3 URLs are generated from the bucket and the path name, so you don’t have to worry about them. You can also specify permissions for your files, in case you don’t want the default public-read, by using :s3_permissions.

You can find more about the S3 Storage options and the Filesystem Storage options at their RDocs.

Keep up to date!

Remember, there’s always the Paperclip Google Group and the Paperclip Lighthouse Account in case you have problems, questions, or feature requests.

Visit our Open Source page to learn more about our team’s contributions.