0

假设我有两个 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 中)。我可以在上面的条件下替换self.articleArticle.find(self.article_id),但这看起来不像它的本意。

这是rails(2.3.11)中的错误还是我做错了什么?非常感谢。

4

1 回答 1

0

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

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

更新:

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

于 2011-09-06T18:56:42.017 回答