Каскадное удаление в моделях 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 UPDATE. Так, есть ли какой-либо способ выполнить это (возможно, сам RoR мог заботиться об удалении связанных комментариев?)?

50
задан tshepang 15 November 2013 в 10:13
поделиться

1 ответ

Да . В ассоциации модели Rails вы можете указать параметр : зависимый , который может принимать одну из следующих трех форм:

  • : destroy /: destroy_all Связанные объекты уничтожаются вместе с этим объектом посредством вызывая их метод destroy
  • : delete /: delete_all Все связанные объекты немедленно уничтожаются без вызова их : destroy method
  • : nullify Внешние ключи всех связанных объектов устанавливаются на NULL без вызова их обратных вызовов save

Обратите внимание, что : Параметр зависимой игнорируется, если у вас настроена ассоциация : 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, внешние ключи устанавливаются на NULL без вызова их обратных вызовов save

. Обратите внимание, что параметр : зависимый игнорируется, если у вас есть : 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, внешние ключи устанавливаются на NULL без вызова их обратных вызовов save

. Обратите внимание, что параметр : independent игнорируется, если у вас есть : 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, Параметр зависимой игнорируется, если у вас настроена ассоциация : 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, Параметр зависимой игнорируется, если у вас настроена ассоциация : 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, без вызова метода 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, без вызова метода 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 , вы получите исключение:

Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, : restrict_with_error,: restrict_with_exception]

87
ответ дан 7 November 2019 в 10:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: