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 UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
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)