run rails migrations generate foreign column belong association ruby-on-rails postgresql referential-integrity

ruby-on-rails - migrations - ruby on rails generate migration



Rieles: eliminar en cascada vs destruir dependiente (3)

Realmente depende del comportamiento que quieras. En el caso 1, se llamará a destroy en cada orden asociado, y por lo tanto, las devoluciones de llamada ActiveRecord . En el caso 2, estas devoluciones de llamada no se activan, pero serán mucho más rápidas y garantizarán la integridad referencial.

En la infancia de una aplicación, recomendaría ir con :dependent => :destroy porque te permite desarrollar de una manera que sea independiente de la base de datos. Una vez que empiece a escalar, debería comenzar a hacerlo en la base de datos por razones de rendimiento / integridad.

Suponiendo que tengo dos tablas: users y orders . Un usuario tiene muchos pedidos, por lo que, naturalmente, hay una clave foránea user_id en mi tabla de pedidos.

¿Cuál es la mejor práctica en los rieles (en términos de velocidad, estilo e integridad referencial) para garantizar que si se elimina un usuario, también se eliminan todas las órdenes dependientes? Estoy considerando las siguientes opciones:

Caso 1. Usando :dependent => :destroy en el modelo de usuario

Caso 2. Definición de las órdenes de mesa en postgres y escritura.

user_id integer REFERENCES users(id) ON DELETE CASCADE

¿Hay alguna razón por la que debería usar el Caso 1? Parece que el caso 2 está haciendo todo lo que quiero que haga? ¿Hay diferencias en términos de velocidad de ejecución?


Usaría la opción 1. Si bien puede funcionar, puedo ver una serie de problemas con la opción 2:

  1. ActiveRecord no sabrá que estos registros se eliminaron, lo que podría provocar un comportamiento inestable
  2. No sería claro para nadie que lea el código que eliminar a un usuario significa que todos sus pedidos también se eliminarán
  3. cualquier controlador de destroy en Orden no dispararía

Ciertamente esperaría que la opción 2 fuera más rápida, pero depende de usted si las compensaciones valen la pena. ¿La eliminación de un usuario es una operación común en su aplicación?

Otra opción sería usar :dependent => :delete_all . Esto sería más rápido que :dependent => :destroy y evitar los inconvenientes 1 y 2 anteriores. Vea here para más detalles.


has_many :orders, dependent: :destroy

  • La opción más segura para mantener automáticamente la integridad de los datos.
  • Tienes asociaciones polimórficas y no quieres usar disparadores.


add_foreign_key :orders, :users, on_delete: :cascade (en la migración de base de datos)

  • No está utilizando ninguna asociación polimórfica o desea utilizar disparadores para cada asociación polimórfica.


has_many :orders, dependent: :delete_all

  • Utilice solo cuando has_many es un nodo de hoja en su árbol de asociación (es decir, el hijo no tiene otra asociación has_many con referencias de clave externa)