Каскадное удаление в моделях Ruby ActiveRecord?
Я смотрел скринкаст на rubyonrails.org (создавал блог).
У меня есть следующие модели:
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
Отношения между моделями работают нормально, за исключением одного - когда я удаляю запись записи, я ожидаю, что RoR удалит все связанные записи комментариев. Я понимаю, что ActiveRecords не зависит от базы данных, поэтому нет встроенного способа создания внешних ключей, отношений, ON DELETE, ON UPDATE. Итак, есть ли способ сделать это (возможно, сам RoR мог бы позаботиться об удалении связанных комментариев?)?
1 ответ
Да. В модельной ассоциации Rails вы можете указать :dependent
опция, которая может принимать одну из следующих трех форм:
:destroy/:destroy_all
Связанные объекты уничтожаются вместе с этим объектом, вызывая ихdestroy
метод:delete/:delete_all
Все связанные объекты уничтожаются немедленно, не вызывая их:destroy
метод:nullify
Внешние ключи всех связанных объектов установлены вNULL
не называя ихsave
обратные вызовы
Обратите внимание, что :dependent
опция игнорируется, если у вас есть :has_many X, :through => Y
Ассоциация создана.
Таким образом, для вашего примера вы можете выбрать удаление сообщения из всех связанных с ним комментариев при удалении самого сообщения без вызова каждого комментария. destroy
метод. Это будет выглядеть так:
class Post < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments, :dependent => :delete_all
end
Обновление для Rails 4:
В Rails 4 вы должны использовать :destroy
вместо :destroy_all
,
Если вы используете :destroy_all
вы получите исключение:
Опция: зависимый должен быть одним из [:destroy,:delete_all,:nullify,:restrict_with_error,:restrict_with_exception]