2008-12-01 12 views
64

Sé que esto es probablemente en Internet, pero no puedo encontrar la respuesta aquí en Stackoverflow, así que pensé que podría aumentar un poco la base de conocimientos aquí.¿Puedo configurar la eliminación de Cascade en Rails?

Soy un novato en Ruby and Rails, pero mi empresa se está poniendo muy bien invertida en ella, así que estoy tratando de conocerla con un poco más de detalle.

Ha sido difícil para mí cambiar de mentalidad al diseño de una aplicación del "modelo" más bien de la base de datos, así que estoy tratando de descubrir cómo haría todo el trabajo de diseño que he hecho clásicamente en la Base de datos en el modelo Rails en su lugar.

Así que la tarea más reciente que me he dado es descubrir cómo configurar un modelo de base de datos Rails para hacer eliminaciones en cascada? ¿Hay una manera fácil de hacer esto? ¿O tendría que entrar en MySql y configurar esto?

Gracias.

-Matt

Respuesta

79

También puede configurar la opción: depende de: delete_all. : delete_all emitirá una sola instrucción SQL para eliminar todos los registros secundarios. debido a esto, usar: delete_all puede brindarle un mejor rendimiento.

has_many :memberships, dependent: :delete_all 
+8

Su explicación es confusa. Se usará una única instrucción SQL, pero no se llamará al método de destrucción para cada fila secundaria. Tienes que usar destroy_all para eso. –

+0

@John: espero que las ediciones aclaren la confusión. gracias por señalar eso. –

+0

@Mike - mucho mejor, gracias. –

58

Sí se puede, si está usando una relación como la que acaba de hacer has_many este

has_many :memberships, dependent: :destroy 
+0

Dan, Así que supongo que mi próxima pregunta es: si ejecuto un comando db migrate ¿eso realmente lo configurará en el db?¿O la cascada está completamente controlada por los rieles? –

+0

Sí, es manejado por rieles. (Sin embargo, asegúrese de que siempre necesite eliminar todas las filas relacionadas) –

+0

@Matt: la línea has_many debe estar en su clase de modelo, la migración no lo agregará. – Gareth

6

Parece que este plugin que podría dar lo que estás buscando si quieres el eliminaciones en cascada refleja en la estructura de base de datos real:

http://www.redhillonrails.org/foreign_key_migrations.html

Formato para el uso de esta en una migración sería somethi ng así:

create_table :orders do |t| 
    t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade 
    ... 
end 
+5

Ese enlace está muerto, pero esta es una alternativa más nueva: http://github.com/matthuhiggins/foreigner – gdelfino

9

Hemos de tener en cuenta que delete_all no ejecutará ningún devoluciones de llamada (como before_destroy y after_destroy) en los registros secundarios.

9

Al contrario de la respuesta proporcionada, sugiero también hacerlo a nivel de base de datos. En caso de que tenga diferentes procesos o un entorno de múltiples hilos, podría suceder que los registros no se eliminen correctamente. Además, la clave externa de la base de datos hace las cosas mucho más rápido cuando se eliminan muchos datos.

Al igual que en la respuesta se sugiere hacer esto:

has_many :memberships, dependent: :delete_all 

Sin embargo Asimismo, asegúrese de configurar un foreign_key en una migración. De esta forma, la base de datos se encarga de eliminar los registros automáticamente.

Para anular los valores cuando se elimina un miembro, suponiendo que tiene un modelo de usuario:

add_foreign_key :users, :memberships, on_delete: :nullify 

También puede eliminar todos los modelos cada vez que una membresía se elimina

add_foreign_key :users, :memberships, on_delete: :cascade 
Cuestiones relacionadas