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 web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
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)