Каскадное удаление в моделях 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]

Другие вопросы по тегам