Let's say I have two ActiveRecord models: LineItem and Article.
class LineItem < ActiveRecord::Base
belongs_to :article
...
end
I'm experiencing the following behaviour on LineItems (Rails 2.3.11):
>> l = LineItem.new
=> #<LineItem id: nil, article_id: nil, ...>
>> l.article_id=10
=> 10
>> l.article
=> #<Article id: 10, ...>
>> l.article_id=20
=> 20
>> l.article
=> #<Article id: 10, ...>
So if article_id already has a value, a subsequent change doesn't change the article association anymore. (At least not immediately - only after save it has been set to the new value.)
This is causing me problems in my validate method when updating existing LineItems. In my LineItems-Controller I do update like this:
def update
@line_item = LineItem.find(params[:id])
@line_item.attributes = params[:data] #params[:data] contains article_id
...
@line_item.save!
...
end
In my LineItem class I have many validations like this (simplified):
def validate
if self.article.max_size < self.size
errors.add_to_base("Too big for chosen article.")
end
end
On updates this validation acts on the 'old' article since the new one is only in self.article_id (but not in self.article) at this point. I could replace self.article
with Article.find(self.article_id)
in the condition above but this doesn't look like the way it's meant to be.
Is this a bug in rails (2.3.11) or am I doing something wrong? Thanks a lot.
It is not a bug you are encountering, but rather the behaviour of the AR association cache. You can force the association to be reloaded during validation by passing true
to the associtaion method: self.article(true)
.
You could also clear all cached assocations for a LineItem instance by calling #clear_association_cache
.
UPDATE:
It actually was a bug, but it has been fixed! (See Alex's comment)