5

根据ActiveRecord::Base的文档:

==(comparison_object) 如果 compare_object 是同一个确切的对象,或者 compare_object 是相同的类型并且 self 有一个 ID 并且它等于 comparison_object.id,则返回 true。

请注意,根据定义,新记录不同于任何其他记录,除非其他记录是接收者本身。此外,如果您使用 select 获取现有记录并忽略 ID,则您只能靠自己,此谓词将返回 false。

另请注意,销毁记录会在模型实例中保留其 ID,因此删除的模型仍然具有可比性。

但我的观察表明,它只比较实例,而不是 id,因此以下是正确的:

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 实例被认为是不同的,而文档明确表示它们应该相等?

更新:平等确实按预期工作上面的代码示例无关紧要。请看下面我的回答。

4

2 回答 2

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)
于 2011-03-16T22:49:04.227 回答
4

仔细查看定义:请注意,根据定义,新记录不同于任何其他记录

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

于 2011-03-16T15:02:59.427 回答