Tuesday, June 3, 2008

My associated records based on time are caching!

I had been working for the last few weeks on a tricky issue. Given the following code:
class Vendor < ActiveRecord::Base

has_many :vlogs, :conditions => ["vlogs.published_at < '#{Time.now.to_s(:db)}'", ]

end


The items listed for each vendor would cache an arbitrary amount of time after the server was started. Restarting mongrel would resolve the issue - until Time was cached again. I spent more hours than I care to think about trying to resolve this issue with various Hashrocket and EngineYard staff. The only solution presented was:

class Vendor < ActiveRecord::Base

has_many :vlogs, :conditions => ["vlogs.published_at < ?", Time.now.to_s(:db)]

end



Which didn't work, anyhow. I finally spent some time with Tim Pope this evening, and he provided the following, correct solution:



class Vendor < ActiveRecord::Base

has_many :vlogs, :conditions => ["vlogs.published_at < '\#{Time.now.to_s(:db)}'", ]

end



The trick here is that Ruby is interpolating the date string; ActiveRecord never even sees the reference to Time.now. Apparently, deep within ActiveRecord, there's a regexp that searches for string to interpolate. The solution, escaping the pound symbol, allows ActiveRecord to find and execute the interpolation.

1 comments:

tsaleh said...

We generally use something along the lines of:

class Vendor < ActiveRecord::Base
has_many :vlogs, :conditions => 'vlogs.published_at < NOW()'
end