¿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? )?
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étododestroy
-
: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 enNULL
sin llamar a sussave
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]
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