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



假设我有两个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已经有一个值,后续的更改不会再改变文章关联。(至少不是立即-只有在保存后设置为新值)

这导致我的验证方法在更新现有的LineItems时出现问题。在我的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中)。在上面的条件下,我可以用Article.find(self.article_id)代替self.article,但这看起来不像它的本意。

这是一个bug在rails(2.3.11)或我做错了什么?非常感谢。

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

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

更新:

这实际上是一个错误,但它已被修复!(见Alex的评论)

最新更新