Dynamic conditions for belongs_to, has_many and has_one associations

Note: Consider not doing this. Use form models or vanilla methods instead.


The :conditions option for Rails associations cannot take a lambda. This makes it hard to define conditions that must be evaluated at runtime, e.g. if the condition refers to the current date or other attributes.

A hack to fix this is to use faux string interpolation in a single-quoted :conditions string:

class User < ActiveRecord::Base
  has_many :contracts
  has_one :current_contract, :class_name => 'Contract', :conditions => '"#{Date.today.to_s(:db)}" BETWEEN start_date AND end_date'
end

The single quotes around the conditions are not a typo. It's to prevent Ruby from interpolating the string at compile time. Rails is aware of this hack and will perform interpolation at runtime.

See this article Show archive.org snapshot for some advanced trickery you can do with this hack.

Rails 3

Starting with Rails 3.0.5 Show archive.org snapshot the trick above is deprecated for this:

has_one :current_contract ..., :conditions => proc { "'#{Date.today.to_s(:db)}' BETWEEN start_date AND end_date" }
Henning Koch About 13 years ago