Recently in a Rails app, I ran into a strange bug.
In this app, we had users and articles. A User could write any number of
Article s.
class User < ActiveRecord::Base
has_many :articles
end
class Article < ActiveRecord::Base
belongs_to :user
end
On a User‘s personal page we show their recent articles. At first I
implemented it using another #has_many like:
class User < ActiveRecord::Base
has_many :articles
has_many :recent_articles,
:class_name => 'Article',
:conditions => ['created_on > ?', 2.weeks.ago]
end
class Article < ActiveRecord::Base
belongs_to :user
end
Now this worked for a day.
This is why.
Say this app went online at 7/15/2007. When that User class was loaded its
#has_many calls got executed once, which means the value of 2.weeks.ago was
7/1/2007. So User#recent_articles would return articles created after
7/1/2007.
On 7/16/2007 User#recent_articles would still return articles created after
7/1/2007. Which is wrong because 2 weeks ago is 7/2/2007 not 7/1/2007.
In other words, ActiveRecord is only going to execute that
User#recent_articles #has_many declaration once. The solution is to create
an instance method instead.
class User < ActiveRecord::Base
def recent_articles
articles.find :all,
:conditions => ['created_on > ?', 2.weeks.ago]
end
end