Blog

I admit, I've never been a big fan of named_scope or just scope as it's been renamed in Rails 3. When it was first introduced I remember not being particularly impressed, as a Merb acolyte we'd had this chaining functionality in Datamapper for ages, only it was much better. In fact in Datamapper, every query you could construct was chainable. Thankfully in Rails 3 and ActiveRecord 3, queries have finally grown up so that everything is now chainable in ActiveRecord too:

But imagine if we want to add a new kind of scope to find user's with a given last name:

scope :by_last_name, lambda { |name| where(:last_name => name) }

It's getting a bit less nice, aside from the gratuitous lambda, it's still pretty okay though.

What I believe is wrong with this code though is that it is essentially recreating Ruby functionality. We're defining a method called by_last_name which will execute some code when called, only we're doing it through meta-programming for essentially no reason at all. The above could have been written as:

def self.by_last_name(name); where(:last_name => name); end

And it would have worked exactly the same. The only difference that I can tell is that scope allows you to define extension methods by passing a block, which I'm sure no one has ever used, since it's so completely useless.

The problem becomes even more striking when the code is even the slightest bit complicated.

Inspired by this post on how to create mirror images with Paperclip, I decided to write up how to do the same thing with CarrierWave. It's a nice example of how CarrierWave's Uploader class makes manipulating files very easy.

This assumes you've already generated an uploader and probably mounted it on a model somewhere. If this doesn't make sense to you, check out the CarrierWave documentation.

This will first create a gradient. It will then flip the image and use that gradient as the alpha channel for the flipped image. Finally it will create a new image, putting the original, and the faded out mirror image together.

Next, add a version to your Uploader, which calls the new add_mirror_effect method: