2011-03-16 13 views
5

De acuerdo con documentos de ActiveRecord::Base:ActiveRecord igualdad de objetos

== (comparison_object) Devuelve cierto si comparison_object es el mismo objeto exacto o comparison_object es del mismo tipo y auto tiene un ID y está igual a comparison_object.id.

Tenga en cuenta que los nuevos registros son diferentes de cualquier otro registro, por definición, menos que el otro disco es el receptor sí. Además, si obtiene registros existentes con seleccionar y deja la ID, está por su cuenta, este predicado devolverá falso.

Tenga en cuenta también que la destrucción de un registro conserva su ID en la instancia de modelo , por lo que los modelos son eliminados todavía comparables.

pero mis observaciones muestran que sólo compara instaces, no identificadores de modo que estas circunstancias:

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 pregunta es se consideran 2 AR casos a ser diferentes, mientras que los documentos dicen explícitamente que esos deben ¿igualarse?

ACTUALIZACIÓN: La igualdad FUNCIONA como se esperaba. La muestra de código anterior es irrelevante. Ver mi respuesta a continuación.

+0

Nota: La versión actual del enlace de documento anterior es en http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method -i-3D-3D – DreadPirateShawn

Respuesta

5

Respondiendo a mi propia pregunta (que es irrelevante).

Todas las comprobaciones de igualdad FUNCIONAN como se esperaba (y se describen en los documentos).
Supongo que la razón por la que no funcionó para mí es que ejecuto autotest y algo podría estar en la memoria caché u otra razón mítica que no puedo explicar en este momento.

En resumen, todas las siguientes afirmaciones son, en efecto pasando:

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 por mencionar el autotest y el almacenamiento en caché, lo que explicaba el problema que tuve cuando estaba con watchr. ¡Gracias! – rdamborsky

4

Mire de cerca la definición: Tenga en cuenta que los nuevos registros son diferentes de cualquier otro registro por definición.

En este caso, como AR normalmente solo hace controles de igualdad a la columna de identidad, puede comparar los dos objetos comparando el resultado de lo que devuelve #attributes para cada uno.

+0

2 registros son diferentes. Pero 2 objetos con el mismo ID son lógicamente iguales (según 'ID .. es igual a comparison_object.id'). Si eso es cierto, no entiendo por qué 'a == b' es' falso' porque debería ser lo mismo que 'a.id == b.id' (que es' verdadero'). ¿O me falta algo? –

+0

Tiene razón, pero este es un caso especial porque la variable a contiene un nuevo registro y, por definición, a no será igual a ningún otro registro. Si lo hiciste User.find (: email ..) == User.find (: email ..) ... Volverá a ser cierto porque no solo son el mismo registro, pero ninguno de ellos es nuevo. –

+0

No. Tanto 'a' como' b' NO son registros nuevos. 'a.new_record?' y 'b.new_records?' son 'false'. Son solo 2 objetos diferentes.Nada que ver con 'User.find (..) == User.find (..)'. Además, en este momento mis especificaciones realmente * funcionan como los documentos dicen * y puedo usar 'a == b'. Supongo que hubo un problema en otro lado. Esto significa que mi pregunta está obsoleta ahora y (como esperaba) 'a == b' son siempre ciertas siempre que tengan la misma ID. –

Cuestiones relacionadas