2010-05-09 11 views
171

En los carriles lo guía es descrito así:Rieles: dependiente =>: destruir VS: dependiente =>: delete_all

objetos serán además destruidos si están asociados con :dependent => :destroy, y se eliminan si están está asociado con :dependent => :delete_all

Right, cool. ¿Pero cuál es la diferencia entre ser destruido y ser eliminado? Intenté ambos y parece hacer lo mismo.

Respuesta

173

La diferencia es con la devolución de llamada.

El :delete_all se realiza directamente en la aplicación y elimina por SQL:

DELETE * FROM users where compagny_id = XXXX 

Con la :destroy, hay una instancia de todos sus hijos. Por lo tanto, si no puede destruirlo o si cada uno tiene su propio :dependent, se pueden llamar sus devoluciones de llamada.

+72

La creación de instancias y la invocación de destroy en cada uno de los objetos secundarios será lenta si tiene muchos hijos (y n^2 si tiene nietos, y así sucesivamente). delete_all es el tipo de solución "nuke it from orbit" que no te importa/no tiene ninguna devolución de llamada before/after destroy en los modelos. –

+4

¡Vea la respuesta más nueva a continuación! – berezovskyi

+5

"Destruirlo desde la órbita" hizo mi día – Andreas

124

En un modelo de asociación rieles se puede especificar la opción :dependent, que puede tomar una de las tres formas siguientes:

  • :destroy/:destroy_all Los objetos asociados son destruidos junto a este objeto llamando a su método destroy
  • :delete/:delete_all Todos los objetos asociados se destruyen inmediatamente sin llamar a su método :destroy
  • :nullify Todas las claves externas de los objetos asociados se configuran en NULL sin llamar sus save devoluciones de llamada
+2

Consulte http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html (busque "anular") para los rdocs autoritativos. – mrm

+20

Desde Rails 3.0 también es posible especificar ': restrict'. _Si se establece en: restringir este objeto no se puede eliminar si tiene un objeto asociado._ – RocketR

+16

no hay opciones ': borrar' o': destruir_todos' por su aspecto? _La opción: dependiente espera ya sea: destroy,: delete_all,: nullify o: restricted (: delete) _ –

26

Ver destruir elimina sus elementos asociados donde delete_all puede borrar múltiples datos de la tabla de auto como DELETE * FROM table where field = 'xyz'

: Opciones posibles dependientes:

controla lo que sucede a la objetos asociados cuando se destruye su dueño. Tenga en cuenta que estos se implementan como devoluciones de llamada, y Rails ejecuta devoluciones de llamada en orden. Por lo tanto, otras devoluciones de llamada similares pueden afectar el comportamiento dependiente, y el comportamiento :dependent puede afectar otras devoluciones de llamada.

:destroy hace que todos los objetos asociados también se destruyan.

:delete_all hace que todos los objetos asociados se eliminen directamente de la base de datos (por lo que las devoluciones de llamada no se ejecutarán).

:nullify hace que las claves foráneas se establezcan en NULL. Las rellamadas no se ejecutan.

:restrict_with_exception hace que se produzca una excepción si hay registros asociados.

:restrict_with_error provoca un error que se agrega al propietario si hay algún objeto asociado.

Si se utiliza con la opción :through, la asociación en el modelo de unión debe ser un belongs_to, y los registros que se eliminan son los registros de combinación, en lugar de los registros asociados.

1

En realidad, la principal diferencia es que no se invocarán las devoluciones de llamada cuando se usó :delete_all. Pero cuando se usa :destroy, se activará la pila de retrollamadas (:after_destroy, :after_commit ...).

En consecuencia, si tiene touch: declaraciones de ing en los modelos que se eliminan, entonces es mejor usar dependent: :delete_all en lugar de 'dependiente:: destruir'.

Cuestiones relacionadas