ActiveRecord: Validation of Associations

Posted: March 12, 2009. Tags: Rails, ActiveRecord

If you have two models associated in some way, it is usual to add a validates_presence_of validator to ensure that the models are connected before saving. However, be aware that there are two ways of doing this with different performance ramifications.

class BlogEntry < ActiveRecord::Base
  belongs_to :blog
  validate_presence_of :blog
end

During validation, validates_presence_of :blog causes ActiveRecord to call self#blog to see if it is nil. As this is the name of the association it will cause AR to retrieve the associated record from the DB before ascertaining if it is nil. E.g. with Rails 2.2.2:

>> e = BlogEntry.find(1)
  BlogEntry Load (0.3ms)   SELECT * FROM "blog_entries" WHERE ("blog_entries"."id" = 1)
=> #
>> e.valid?
  Blog Load (0.3ms)   SELECT * FROM "blogs" WHERE ("blogs"."id" = 1)
=> true

If you are confident of your database integrity (and you are using foreign key constraints, right), you can do validates_presence_of :blog_id instead. This will save you an SQL query. In a model that is saved frequently, this can be quite beneficial.

class BlogEntry < ActiveRecord::Base
  belongs_to :blog
  validate_presence_of :blog_id
end