Rails has_many relation: a look at object_ids



Rails 2.3.14 中发生了一些奇怪的事情。任何想法为什么会发生以下情况?

假设我们有这样的类

class Article < ActiveRecord::Base
   has_many :prices
end
class Price < ActiveRecord::Base
end

然后在irb会话中发生以下情况。

>> a = Article.first
=> #<Article id: 980190962>
>> a.prices.first.object_id
=> 97498070
>> a.prices.first.object_id
=> 97470500
>> a.prices.first.object_id
=> 97451010
>> a.valid?
=> true
>> a.prices.first.object_id
=> 97374790
>> a.prices.first.object_id
=> 97374790

因此,起初每次访问记录时,object_id都会更改(是的,它始终是相同的)。稍后调用 #valid? 此行为将停止。相反,一切都很好。每次调用都会得到相同的对象。

为什么这很重要?

假设您向Price添加验证

class Price < ActiveRecord::Base
  validates_presence_of :amount
end

然后,您要更改商品的价格。

>> a = Article.first
=> #<Article id: 980190962>
>> p = a.prices.first
=> #<Price id: 280438907, amount: 1.0, article_id: 980190962>
>> p.amount = nil # oops, accidentally we assigned nil
=> nil
>> p.valid?
=> false
>> a.valid?
=> true

什么?价格无效,但文章不是?这不应该发生,因为默认情况下,has_many:validate选项设置为 true 。发生这种情况是因为object_id的变化

每个新的上下文(请求/响应)都将重新生成对象 ID。当您运行查询a.prices.first.object_id时,它每次都会命中查询以获得第一个价格,并且每次命中都会生成新的对象 ID。

但是在第二种情况下,您已将第一个价格提取到实例变量中并对其进行处理,因此没有新的请求/响应进入数据库,因此它提供相同的对象IDS。

相关内容

  • 没有找到相关文章

最新更新