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。