¿Eliminar en cascada en modelos de Ruby ActiveRecord?


Estaba siguiendo el screencast en rubyonrails.org (creando el blog).

Tengo los siguientes modelos:

Comentario.rb

class Comment < ActiveRecord::Base
    belongs_to :post
    validates_presence_of :body # I added this
end

Post.rb

class Post < ActiveRecord::Base
    validates_presence_of :body, :title
    has_many :comments
end

Las relaciones entre modelos funcionan bien, excepto por una cosa: cuando elimino un registro de post, esperaría que RoR eliminara todos los registros de comentarios relacionados. Entiendo que ActiveRecords es independiente de la base de datos, por lo que no hay una forma incorporada de crear sentencias foreign key, relations, ON DELETE, ON UPDATE. Entonces, ¿hay alguna manera de lograr esto (tal vez el propio RoR podría encargarse de eliminar los comentarios relacionados? )?

Author: Tshepang, 2009-12-13

1 answers

Sí. En una asociación de modelos Rails puede especificar la opción :dependent, que puede tomar una de las tres formas siguientes:

  • :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 :destroy
  • :nullify Todas las claves foráneas de los objetos asociados se establecen en NULL sin llamar a sus save devoluciones de llamada

Tenga en cuenta que el :dependent la opción se ignora si tiene configurada una asociación :has_many X, :through => Y.

Así que para su ejemplo, puede elegir que un post elimine todos sus comentarios asociados cuando se elimine el post en sí, sin llamar al método destroy de cada comentario. Eso se vería así:

class Post < ActiveRecord::Base
  validates_presence_of :body, :title
  has_many :comments, :dependent => :delete_all
end

Actualización para Rails 4:

En Rails 4, debe usar :destroy en lugar de :destroy_all.

Si usas :destroy_all, obtendrás la excepción:

La opción: dependiente debe ser una de [: destroy, :delete_all, :anular, : restrict_with_error,: restrict_with_exception]

 78
Author: John Topley,
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
2016-06-29 14:45:54