Much of the beauty of ActiveRecord associations is in the collection methods that are provided for you when you define has_many relationships.
For instance, when we say:
class Organization < ActiveRecord::Base
has_many :people
end
We now have an organization.people method that returns the collection of associated people within the organization. Easy enough. We also get nice little methods on the collection of people like organization.people<<, organization.people.build, organization.people.create and organization.people.find (among others). Well what if you wanted to define your own method on this auto-magically provided collection method? You do this through Association Extensions which let you define methods to add to the collection. You can define an association extension either with a block or a module – we’ll use a block provided to the has_many call here as it’s the most common way to do so:
class Organization < ActiveRecord::Base
has_many :people do
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
end
I’ve defined a find_active method which will retrieve all people in the organization that have the active column set to true. This can be invoked very intuitively with:
organization.people.find_active
This is a great way to provide convenience finder methods for common retrievals on the associated collection.
If you want to define an extension as a module just provide the:extend option in your has_many definition:
module FindActiveExtension
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
class Organization < ActiveRecord::Base
has_many :people, :extend => FindActiveExtension
end
You can customize to your heart’s content – these are just some simplistic examples of how to plug into this nifty feature. I just recently stumbled upon it and thought it might be worth spreading the word since I found myself smitten by it.
Resources
tags: rails, activerecord, rubyonrails

class << selfsegment. (Oops - yeah, I was aware of the other part - I when I posted I meant to copy the code out of your comment, Michael, but accidentally copied Ryan's.)class Activity < ActiveRecord::Base has_many :actions end class Action < ActiveRecord::Base belongs_to :activity def self.first_inbound return @first_inbound ||= find( :first, :conditions => "type = 'inbound'", :order => "action_date asc" ) end endEven though you can still reference that method as activity.actions.first_inbound, the first time you run it, the instance variable gets set *regardless of controlling object*. What this means is that if you're iterating through a collection of Activity objects, every time you call the first_inbound method after the first, you're going to get the same data. This is very, very bad. Encapsulating your association extensions inside the code block of the association call keeps the instance variables separately scoped through calls to the collection. That way, activities[0].actions.first_inbound will give you what you expect, as will activities[1].actions.first_inbound. While it might not look as good, the behavior is what you will ultimately want.