2011-03-16 76 views
5

ActiveRecord::Base文檔:ActiveRecord的對象的相等

==(comparison_object)如果comparison_object是完全相同的 對象,或comparison_object是 相同類型的和自具有ID,它是,則返回true 等於comparison_object.id。

請注意,除了其他記錄是 接收器本身,新記錄不同於 定義的其他記錄, 。此外,如果您使用select取 現有記錄並將 ID取出,則您自行處理,此謂詞將返回false。

還要注意的是,銷燬記錄 保留其ID在模型 實例,所以刪除車型仍然 可比性。

但我的觀察表明,它只是使下列情況,比較instaces,不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實例被認爲是不同的,而文檔明確地說,那些應等於?

更新:等於是否按預期工作以上代碼示例無關。請參閱下面的答案。

+0

注:以上文檔的鏈接的當前版本是在http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method -i-3D-3D – DreadPirateShawn

回答

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) 
+0

+1提及自動測試和緩存,這解釋了我與守護者一樣的問題。謝謝! – rdamborsky

4

仔細查看定義:請注意,新記錄與定義爲的任何其他記錄不同。

在這種情況下,由於AR通常只是對標識列進行相等性檢查,因此可以通過比較兩個對象的#attributes返回結果來比較兩個對象。

+0

2個記錄不同。但是具有相同ID的兩個對象在邏輯上是相等的(根據'ID ..等於compare_object.id')。如果這是真的,我不明白爲什麼'a == b'是'false',因爲它應該與'a.id == b.id'(這是'true')相同。或者我錯過了什麼? –

+0

你是對的,但這是一個特殊情況,因爲變量a包含一個新記錄,根據定義,a不會等於任何其他記錄。如果你做了User.find(:email ..)== User.find(:email ..)..它將返回true,因爲它們不僅是同一個記錄,而且它們都不是新的。 –

+0

不是,'a'和'b'都不是新記錄。 'a.new_record?'和'b.new_records?'是'false'。他們只是2個不同的對象。'User.find(..)== User.find(..)'無關。此外,現在我的規格實際上*作爲文檔說*,我可以使用'a == b'。我猜其他地方還有問題。這意味着我的問題現在已經過時,並且(如我所料)只要具有相同的ID,'a == b'總是正確的。 –