Read more

Dynamic conditions for belongs_to, has_many and has_one associations

Henning Koch
February 04, 2011Software engineer at makandra GmbH

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


Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

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" }
Posted by Henning Koch to makandra dev (2011-02-04 11:24)