2011-03-16 18 views
5

:comparison_objectは全く同じ オブジェクトである、又はcomparison_objectは 同じタイプのものであり、自己のIDを持っており、それがある場合ActiveRecordのオブジェクト等価

==(comparison_object)がtrueを返しcomparison_object.idと等しい

他のレコードが受信者自身 でない限り、新しいレコードは定義によって他のレコードと異なる であることに注意してください。また、 の既存のレコードを選択して取り出し、 のIDをそのまま残しておけば、あなた自身はこの 述語はfalseを返します。記録 を破壊するので、削除されたモデルは まだ匹敵する、モデル インスタンスにそのIDを保持することを

も注意してください。

しかし、私の観察は、以下に該当するように、それだけでinstacesではなく、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インスタンスが異なると考えられていますさ平等ですか?

更新:等価は、期待通りに動作します上記のコードサンプルは無関係です。下の私の答えを見てください。

+0

注:上記のドキュメントリンクの現在のバージョンはhttp://api.rubyonrails.org/classes/ActiveRecord/Core.html#methodであります-i-3D-3D – DreadPirateShawn

答えて

5

私自身の質問に答える(これは無関係です)。

すべての等価性チェックDOは、期待通りに機能します(ドキュメントにも記載されています)。
私は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はID列に対して等価チェックを実行するだけなので、#attributesが返す結果をそれぞれ比較して2つのオブジェクトを比較できます。

+0

2レコードが異なっています。しかし、同じIDを持つ2つのオブジェクトは論理的に等価です( 'ID .. is equal to compare_object.id'による)。それが真であれば、 'a == b.id'(' true')と同じでなければならないので、なぜ 'a == b'が' false'なのか理解できません。それとも私は何かが足りない? –

+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'を使うことができます。私はどこかに問題があったと思う。これは、私の質問が今では時代遅れであり、(私が期待したように) 'a == b'は同じIDを持つ限り、常に真であることを意味します。 –