ruby on rails - rails - Eliminar en cascada en los modelos Ruby ActiveRecord?
llaves foraneas ruby on rails (1)
Estaba siguiendo el screencast en rubyonrails.org (creando el blog).
Tengo los siguientes modelos:
comment.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 los modelos funcionan bien, excepto por una cosa: cuando borro un registro de entrada, espero que RoR elimine todos los registros de comentarios relacionados. Entiendo que ActiveRecords es independiente de la base de datos, por lo que no existe una forma incorporada de crear claves foráneas, relaciones, ON DELETE, ON UPDATE. Entonces, ¿hay alguna manera de lograr esto (tal vez RoR podría encargarse de eliminar los comentarios relacionados?)?
Sí. En la asociación de modelos de Rails puede especificar la opción :dependent
, que puede tomar una de las siguientes tres formas:
-
:destroy/:destroy_all
Los objetos asociados se destruyen junto a este objeto llamando a su método dedestroy
-
:delete/:delete_all
Todos los objetos asociados se destruyen inmediatamente sin llamar a su método:destroy
-
:nullify
Todas las claves externas de los objetos asociados se establecen enNULL
sin llamar a sus callbacks desave
Tenga en cuenta que la opción :dependent
se ignora si tiene :has_many X, :through => Y
asociación configurada.
Por lo tanto, para su ejemplo, puede optar por tener una publicación para eliminar todos los comentarios asociados cuando se elimine la publicación, sin llamar al método de destroy
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, debes usar :destroy
lugar de :destroy_all
.
Si usa :destroy_all
, obtendrá la excepción:
La opción: dependiente debe ser una de [: destroy,: delete_all,: nullify,: restrict_with_error,: restrict_with_exception]