eliminar todo vs destruir todo?


Estoy buscando el mejor enfoque para eliminar registros de una tabla. Por ejemplo, tengo un usuario cuyo ID de usuario está en muchas tablas. Quiero eliminar este usuario y todos los registros que tengan su ID en todas las tablas.

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete

Esto funciona y elimina todas las referencias del usuario de todas las tablas, pero escuché que destroy_all era muy pesado en el proceso, así que intenté delete_all. Solo elimina al usuario de su propia tabla de usuarios y el id de todas las otras tablas se hacen null, pero deja los registros intactos en ellos. ¿Puede alguien compartir cuál es el proceso correcto para realizar una tarea como esta?

Veo que destroy_all llama a la función destroy en todos los objetos asociados, pero solo quiero confirmar el enfoque correcto.

Author: the Tin Man, 2011-07-14

4 answers

Tienes razón. Si desea eliminar el Usuario y todos los objetos asociados -> destroy_all Sin embargo, si solo desea eliminar el Usuario sin suprimir todos los objetos asociados-> delete_all

Según este post : Rails: dependent=>: destroy VS: dependent =>: delete_all

  • destroy / destroy_all: Los objetos asociados se destruyen 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 destruir
 199
Author: Sandro Munda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:17

Delete_all es una única sentencia SQL DELETE y nada más. destroy_all llama a destroy () en todos los resultados coincidentes de :conditions (si tiene uno) que podrían ser al menos sentencias SQL NUM_OF_RESULTS.

Si tienes que hacer algo drástico como destroy_all() en un conjunto de datos grande, probablemente no lo haría desde la aplicación y lo manejaría manualmente con cuidado. Si el conjunto de datos es lo suficientemente pequeño, no te haría tanto daño.

 19
Author: Ryan Her,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 20:45:16

Para evitar el hecho de que destroy_all instancie todos los registros y los destruya uno a la vez, puede usarlo directamente desde la clase model.

Así que en lugar de :

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all

Puedes hacer:

u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"

El resultado es una consulta para destruir todos los registros asociados

 16
Author: simon-olivier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 13:06:56

He creado una pequeña gema que puede aliviar la necesidad de eliminar manualmente los registros asociados en algunas circunstancias.

Esta gema añade una nueva opción para las asociaciones ActiveRecord:

Dependiente:: delete_recursively

Cuando se destruye un registro, todos los registros que se asocien con esta opción se eliminarán recursivamente (es decir, entre modelos), sin instanciar ninguno de ellos.

Tenga en cuenta que, al igual que dependent: :delete o dependent: : delete_all, esta nueva opción no activa las devoluciones de llamada around/before/after_destroy de los registros dependientes.

Sin embargo, es posible tener asociaciones dependent: :destroy en cualquier lugar dentro de una cadena de modelos que están asociados con dependent: :delete_recursively. La opción: destroy funcionará normalmente en cualquier lugar arriba o abajo de la línea, instanciando y destruyendo todos los registros relevantes y, por lo tanto, también activando sus devoluciones de llamada.

 1
Author: Janosch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-11 19:43:52