ActiveRecord Association Extensions

Today I want to address what I consider to be one of the most misused features of ActiveRecord.
It is called ActiveRecord Association Extensions.

How to Define An Association Extension

Association Extensions lets you easily add functionality or alter exisiting functionality when dealing with ActiveRecord association. I will refer the following simple code in the post:

What we have here is a User model which has_many Account models. Dead simple.

In order to extend the accounts association all we have to do is add a block to it as in:

Which lets us access @user.accounts.recent as expected.

Use Scopes When It’s Right

The first (and obvious) thought about the latest code snippet is “Why would you wanna do that? Why not just use scope :recent on Account model?!”.
To that I’d answer You’re damn right! This logic should definitely belong to the Account model and be used as a scope so that other references to Account will be able to use it as well.

A Good Case For Association Extensions

This was an easy one and probably not the reason you’re reading this – I want to introduce to you with another case which yells association extenstion a bit louder: Let’s say I want that every account which is added to a user accounts collection will have the kind “UserAccount” as a property.

I will note here that every has_many association includes the << method which may be used as @user.accounts << Account.new

One way to achieve my goal would be to verify that every time I add an account to a user accounts collection I remember to set its kind property to "UserAccount". Counting on your memory skills (or even worse – on other programmers memory skills) is a bad habbit, believe me :)

A better way would be to define a method named add_account(account) in the User model which will set account.kind = "UserAccount" before adding it to the accounts collection.

But why should we invent the wheel? ActiveRecord has already taken care of this, presenting you the ultimate solution:

We've practically overriden the << method of ActiveRecord association, and by doing this we have the following benefits:

1. We're using ActiveRecord's conventions. Rails is known for its "Convention Over Configuration" attitude and although it may seem negligible this is a huge benefit on its own.

2. We don't have to remember to set anything manually, the setting of the kind proprety will be transparent to us in future uses.

3. Isn't that just beautiful?

One thing to note here that the self reference inside the extension method is NOT the user instance, in order to get that we used proxy_association.owner

Resusable Extensions

Another great thing about association extensions is they are reusable. In order to make an extension reusable all you have to do is to extract the methods into a module and :extend that module in the association statement as follows:

Nice, clean and handy.

,

  1. #1 by psylone on August 14, 2013 - 8:53 am

    Very interesting thing! Thanks for this tip )

  1. ActiveRecord and In-Memory Object State « Ruby on Rails Insights

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: