2011-03-16 4 views
5

Secondo documenti di ActiveRecord::Base:ActiveRecord uguaglianza oggetto

== (comparison_object) restituisce true se comparison_object è lo stesso oggetto esatto , o comparison_object è dello stesso tipo e l'auto ha un ID ed è uguale a comparison_object.id.

Nota che i nuovi record sono diversi da qualsiasi altro disco per definizione, a meno che il documento è il ricevitore stesso. Inoltre, se si prelevano i record esistenti con con select e si lascia l'ID, si è da soli, questo predicato restituirà false.

Si noti inoltre che distruggere un record conserva la sua ID nel caso del modello , modelli in modo eliminati sono ancora comparabili.

Ma le mie osservazioni mostrano che mette a confronto solo instaces, non ids modo che segue sono vere:

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 

La questione è di 2 AR casi sono considerati diversi, mentre i documenti esplicitamente dicono che coloro che dovrebbero essere uguale?

UPDATE: L'uguaglianza FUNZIONA come previsto. Il codice sopra riportato non è pertinente. Vedi la mia risposta qui sotto.

+0

Nota: La versione attuale del collegamento doc sopra è a http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method -i-3D-3D – DreadPirateShawn

risposta

5

Rispondere alla mia domanda (che è irrilevante).

Tutti i controlli di uguaglianza funzionano come previsto (e descritti nei documenti).
Suppongo che il motivo per cui non ha funzionato per me è che eseguo autotest e qualcosa potrebbe essere memorizzato nella cache o qualche altra ragione mitica che non riesco a spiegare in questo momento.

In sintesi, tutte le seguenti affermazioni sono infatti passati:

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 per aver menzionato l'autotest e il caching, che spiegava il problema che avevo avuto con watchr. Grazie! – rdamborsky

4

Osservare più da vicino la definizione: Si noti che i nuovi record sono diversi da qualsiasi altro record per definizione.

In questo caso, poiché AR esegue normalmente solo i controlli di uguaglianza sulla colonna Identity, è possibile confrontare i due oggetti confrontando il risultato di ciò che #attributes restituisce per ciascuno.

+0

2 record sono diversi. Ma 2 oggetti con lo stesso ID sono logicamente uguali (secondo 'ID .. è uguale a comparison_object.id'). Se ciò è vero, non capisco perché 'a == b' sia' false' perché dovrebbe essere uguale a 'a.id == b.id' (che è' true'). O mi manca qualcosa? –

+0

Sei corretto, ma questo è un caso speciale perché la variabile a contiene un nuovo record, e per definizione a non sarà uguale a nessun altro record. Se hai fatto User.find (: email ..) == User.find (: email ..) .. Restituirà vero perché non solo sono lo stesso record ma nessuno di essi è nuovo. –

+0

No. Entrambi 'a' e' b' NON sono nuovi record. 'a.new_record?' e 'b.new_records?' sono 'false'. Sono solo 2 oggetti diversi.Niente a che vedere con 'User.find (..) == User.find (..)'. Inoltre, al momento le mie specifiche funzionano * come dicono i documenti * e posso usare 'a == b'. Immagino ci fosse un problema da qualche altra parte. Ciò significa che la mia domanda è obsoleta ora e (come mi aspettavo) 'a == b' sono sempre vere fintanto che hanno lo stesso ID. –