ActiveRecord对象相等

时间:2011-03-16 14:58:23

标签: ruby-on-rails ruby activerecord rspec rspec-rails

根据ActiveRecord::Base的文件:

  

==(comparison_object)如果comparison_object完全相同,则返回true   对象,或者compare_object是   相同的类型和自己有一个ID,它是   等于comparison_object.id。

     

请注意,新记录不同   根据定义,从任何其他记录,   除非另一个记录是   接收器本身。此外,如果你取   选择和离开的现有记录   身份证,你自己,这个   谓词将返回false。

     

还要注意销毁记录   在模型中保留其ID   实例,所以删除的模型仍然是   可比性。

但是我的观察结果表明它只比较了实例,而不是ids,因此以下是真实的:

a = Factory.create(:user)
b = User.find_by_email(a.email) # b is logically same as a

a.id.should == b.id # All good
a.should == b # FAILS: Contradicts the docs
a.should_not == b # Contradicts the docs
a.should_not eql b # Contradicts the docs

问题是2个AR实例被认为是不同的,而文档明确表示那些应该是相同的?

更新:相等按预期工作上面的代码示例无关紧要。请参阅下面的答案。

2 个答案:

答案 0 :(得分:5)

回答我自己的问题(这是无关紧要的)。

所有等同性检查都按预期工作(并在文档中描述) 我认为它对我不起作用的原因是我运行autotest并且可以缓存某些内容或者其他一些我现在无法解释的神话原因。

总而言之,以下所有断言确实都在传递:

a = Factory.create(:user)
b = User.find_by_email(a.email) # b is logically same as a

a.id.should == b.id
a.should == b
a.should eql b
User.find_by_email(a.email).should == User.find_by_email(a.email)
a.should == User.find_by_email(a.email)
b.should == User.find_by_email(a.email)

答案 1 :(得分:4)

仔细阅读定义:请注意,根据定义,新记录与任何其他记录不同

在这种情况下,由于AR通常只是对标识列进行等式检查,因此您可以通过比较每个对象的#attributes返回结果来比较这两个对象。