ActiveRecord trick

Just ran into something and wanted to jot it down to remember it. ActiveRecord objects have two different methods of accessing their associated data: @foo and foo. The former references the container for the data and the latter references the accessor method. There is a subtle but monsterous difference between these two.

Unlike Hibernate which uses custom containers for its associations, ActiveRecord uses plain collections to store associated data (I’m partially guess here from the behavior I’ve seen. I haven’t verified this in the ActiveRecord code). This means that if you want to use associations you MUST reference them using the accessor, even if you are inside the ActiveRecord class. Here’s an example:

class User < ActiveRecord::Base
  has_many :roles

  def is_admin
    @roles.each do |r|
      # This will never be executed
    end

    roles.each do |r|
      # This will be executed
    end
    ...
  end
end

The accessor is where the code that loads the associations lives, not in the collection. This could probably be fixed in upcoming releases and might be (I haven’t played with 1.1 yet).

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 )

Facebook photo

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

Connecting to %s