---
title: What Good is a Flexible Paperclip?
teaser: Paperclip has some new features!
tags: news,web,rails,open source,paperclip
author: Jon Yurek
published_on: 2008-12-30
---

![Originally found at http://flickr.com/photos/toofarnorth/9984261][flickr]

[flickr]: http://images.thoughtbot.com/ui/2008-12-30-9984261_a175c25c62_m.jpg
  "Originally found at http://flickr.com/photos/toofarnorth/9984261"

Since it's the Holidays, I've been spending a bit more time than normal on
[Paperclip](http://thoughtbot.com/projects/paperclip/). And since that time has
been particularly fruitful and there's been a release or two, I figured I should
probably tell someone about it before I friggin' explode. It's all about making
Paperclip more flexible, more adaptable, and more friendly to use. Can you
believe there's more to file uploads than avatars?

## Newer, more sensible defaults

Overall, this is actually a bit small on the change meter, but it may affect
some of you, so it's up front. The :path and :url defaults have changed. By
default now, files will be saved to
`:rails_root/public/system/:attachments/:id/:style/:basename/:extension`. It's
the system part of that that's important, because now it means that if you're
deploying with Capistrano, you don't have to do anything and your attachments
will survive deployments. This was not previously the case, regrettably, but it
is now!

## Callbacks and such

Thanks to the callback methods pioneered by ActiveRecord itself with the
fantastic `before_save` and family, Paperclip now defines a
`before_post_process` and `after_post_process` callback, which can be used
exactly like all the AR callbacks. Not only that, if you're the kind of person
who likes to have more than one attachment on a model, there are per-attachment
callbacks as well, called `before_<attachment>_post_process` and
`after_<attachment>_post_process`. The `before_` callbacks are fully capable of
stopping processing if they need to, simply by returning `false` (not `nil`, but
`false`, which is a distinction ActiveRecord makes, as well). Thus, if you are
uploading images that have E in the name, you can write a `before_post_process`
that looks like this:

```ruby
class User < ActiveRecord::Base
  has_attached_file :avatar, :styles => {:tiny => "32x32#" }
  before_post_process :check_avatar_name_for_capital_e

  def check_avatar_name_for_capital_e
    not self.avatar.original_filename.match(/E/)
  end
end
```

This will prevent the image from being thumbnailed. It will **not** prevent the
attachment from being saved, though. Just from being processed. As a bonus,
something else that will prevent attachments from being processed is failing
validation. If you have a size, content_type, or presence validation that fails,
the attachment will not go through processing (which means ImageMagick won't try
to convert that Word Doc into a <abbr title="Portable Network
Graphics">PNG</abbr> if you don't want it to).

## Expanded Post-Processing

I realize that there's more to image uploads than thumbnailing. And there's more
to file uploads than images. But until now, all you could do was thumbnail your
images. What gives! Well, starting now you can define your own processors that
can do whatever you want to your uploads. **You can:**

* add rounded corners
* invert
* rotate
* <abbr title="Optical Character Recognition">OCR</abbr>
* pick out every third word of your text docs
* run spellcheck
* automatically print them out

... well, you can if you can write code, since none of those exist yet. The only
one that's written is still the thumbnailer/format converter.

But the point is that now you can have Paperclip do whatever you want. Check out
the [Paperclip::Processor class][processor-class] documentation for more info on
exactly what you need to do to make a Processor, but the gist is that you'll
take in a file and some options, and you spit back out a file. That's pretty
much it, and Paperclip places no limits on what you can do, say, or call during
that time (so if you spend 30 seconds rendering a POVRay scene, that's your
fault for making your users wait).

[processor-class]: http://dev.thoughtbot.com/paperclip/classes/Paperclip/Processor.html

Paperclip will automatically detect files in your Rails app's
`lib/paperclip_processors` directory, so just drop them there and you'll be
running in no time.

## The Code

As always, the code is [available for forking and cloning on
GitHub](http://github.com/thoughtbot/paperclip), and [the documentation is
available on our site](http://dev.thoughtbot.com/paperclip/).

If you'd like to contribute to paperclip with a patch, bug report, or feature
request, don't hesitate to get on over to [the Paperclip Google
group](http://groups.google.com/group/paperclip-plugin), or [our Paperclip
Lighthouse](http://thoughtbot.lighthouseapp.com/projects/8794-paperclip/overview).
As much as we like GitHub, we don't really work well with pull requests from
there. Creating a LH ticket with a link to the branch you want us to pull works
much better.

Visit our [Open Source page](https://thoughtbot.com/open-source) to learn more about our team's contributions.
