Associations are the Best

Posted by John Wulff Sun, 10 Jun 2007 09:58:00 GMT

Imagine an application with simple Person and Article models. The Article model has a foreign key: person_id. In this application the best way to get the latest Article for a Person is:
class Person < ActiveRecord::Base
  has_one :latest_article,
          :class_name => 'Article',
          :order => 'articles.published_at DESC'
end
Why an association? Because associations are great. Sure, you’ve probably already got an association for a Person’s Articles. Something like:
has_many :articles,
         :order => 'articles.published_at DESC'
And, you could just leverage that association to get the same result:
person.articles.first
But that’s bad because you’d be loading all the Person’s Articles form the database just to snag the most recent one. You could also do something like this:
class Person < ActiveRecord::Base
  def latest_article
    articles.find :first,
                  :conditions => 'articles.published_at DESC'
  end
end

That’d be a lot better than grabbing all the Articles but it still wouldn’t be great. Multiple calls to person.latest_article would execute multiple calls to the database. Slow.

Using associations is sexier than a simple finder method because you get caching for free. After the first person.latest_article call subsequent calls hit the cache. Very nice.

Now, for the impetus of this post. I was implementing just what I’ve outlined here, only slightly more complex. Instead of Articles simply belonging to People, in my application Articles belong to People through Mentions.

In this scenario, the latest_article association shown above doesn’t work because you cannot (yet) have has_one_through associations. You can do has_many_through to your hearts content, just no has_one_through.

I’m not the first to want this feature.

Much like my ticket regarding the lame behavior of validates_presence_of, it looks like this won’t be resolved soon.

Oh well, I guess I’ll have to write a dreaded finder method.