假设我有两个ActiveRecord模型:LineItem和Article。
class LineItem < ActiveRecord::Base
belongs_to :article
...
end
我在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, ...>
因此,如果article_id已经有值,则后续更改不会再更改文章关联。 (至少不是立即 - 只有在保存后才将其设置为新值。)
在更新现有LineItem时,这会导致我的验证方法出现问题。在我的LineItems-Controller中,我会像这样更新:
def update
@line_item = LineItem.find(params[:id])
@line_item.attributes = params[:data] #params[:data] contains article_id
...
@line_item.save!
...
end
在我的LineItem类中,我有很多这样的验证(简化):
def validate
if self.article.max_size < self.size
errors.add_to_base("Too big for chosen article.")
end
end
在更新时,此验证对“旧”文章起作用,因为此时新文章仅在self.article_id中(但不在self.article中)。我可以在上述条件中将self.article
替换为Article.find(self.article_id)
,但这看起来不像它的意思。
这是rails(2.3.11)中的错误还是我做错了什么?非常感谢。
答案 0 :(得分:0)
这不是您遇到的错误,而是AR关联缓存的行为。您可以通过将true
传递给关联方法self.article(true)
来强制在验证期间重新加载关联。
您还可以通过调用#clear_association_cache
来清除LineItem实例的所有缓存关联。
更新:
它实际上是一个错误,但它已被修复! (见亚历克斯的评论)