通过_id属性更新AR关联不会更新关联对象(在验证之前)

时间:2011-09-06 18:01:07

标签: ruby-on-rails validation activerecord associations updating

假设我有两个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)中的错误还是我做错了什么?非常感谢。

1 个答案:

答案 0 :(得分:0)

这不是您遇到的错误,而是AR关联缓存的行为。您可以通过将true传递给关联方法self.article(true)来强制在验证期间重新加载关联。

您还可以通过调用#clear_association_cache来清除LineItem实例的所有缓存关联。

更新:

它实际上是一个错误,但它已被修复! (见亚历克斯的评论)