¿Por qué ActiveRecord no es lo suficientemente inteligente como para saber que el object_id del padre debe ser igual al object_id del padre de sus hijos?

@father = Hierarchy.find(:first, :conditions => ['label = ?', 'father']) @father.children.each do |child| puts @father.object_id == child.parent.object_id end 

Habría pensado que los resultados aquí serían todos true .

En su lugar, todos son false .

¿Por qué ActiveRecord funciona de esta manera en lugar de reconocer que estos son los mismos objetos de Ruby?

Para devolver los objetos existentes cuando sea posible, en lugar de crear otros nuevos, ActiveRecord tendría que realizar un seguimiento de qué objetos se crearon y a qué entrada en la base de datos responden, lo que sería una sobrecarga. Incluso en ese caso, aún tendría que buscar a child.parent en la base de datos para saber que es la misma entrada que representa @father, por lo que no habría un rendimiento considerable en cuanto al rendimiento de este almacenamiento en caché (bien en el lado de ruby ​​es seguro asignar múltiples objetos pero a costa de la sobrecarga de contabilidad, pero en el lado de la base de datos debería ser básicamente el mismo).

Entonces, dado que la gente de AR probablemente decidió que prevenir diferentes objetos correspondientes a la misma entrada de la base de datos sería perjudicial o, al menos, no valdría la pena el esfuerzo, por lo que optaron por no hacerlo.

Para cualquier persona que haya tropezado en estos años después de que se lo pidiera (¡como a mí!), Visite https://stackoverflow.com/a/4116397/1000655 .

Se sugiere utilizar :inverse_of para configurar asociaciones bidireccionales. ¡Desearía no haber hojeado tantas veces la documentación en el pasado!

ID de objeto es el puntero (tipo de) al objeto. La carga de objetos de Rails no “comparte” espacio de memoria, por lo que está obteniendo una copia del objeto principal cuando lo hace child.parent. Para entender esto, puedes hacer parent.something = foo, y luego comparar child.parent.something y verás que son diferentes. Tendría que volver a cargar el hijo desde la base de datos antes de que refleje los cambios en el objeto principal.

Sin embargo, las probabilidades son que está utilizando el valor de ID incorrecto. Si desea el ID de ActiveRecord (por ejemplo, el valor de la columna de ID en su DBMS de SQL), use @ father.id == child.parent.id

Reutilizar objetos es problemático. ¿Qué sucede si realiza cambios en una instancia del modelo, pero antes de guardarla, realiza otra búsqueda que devuelve ese mismo objeto? El nuevo debería reflejar la base de datos, pero el anterior aún debería tener los datos modificados.

Así que sí, sería una gran cantidad de gastos generales realizar un seguimiento de cada instancia y los campos sucios en cada uno. El ahorro de memoria no valdría la pena.

En lo que a mí respecta, AR debería al menos admitir un complemento del Mapa de Identidad. Este es el mayor problema con el que trato cuando trabajo con AR. Me doy cuenta de que agrega cierta sobrecarga, pero la sobrecarga de la memoria de corta duración es mejor que el impuesto indebido en la base de datos haciendo que extraiga los mismos registros una y otra vez. Es como GC. Puede hacerlo usted mismo o puede usar un lenguaje de alto nivel para abstraerlo y concentrarse en la lógica empresarial. Puede realmente esforzarse para optimizar su AR o puede aprovechar el Mapa de Identidad.