: dependent =>: delete on belongs_to не удаляет объект владельца

Я проверял параметры метода belongs_to и тестировал следующее поведение в Rails 3.2.7

Как указано выше, опция :dependent указывает, что

Если установлено: destroy, связанный объект уничтожается, когда это объект есть. Если установлено значение: delete, связанный объект удаляется без вызывая его метод уничтожения.

Как я понимаю, автор должен быть удален, если Post удаляется в следующем случае:

class Post < ActiveRecord::Base
  belongs_to :author, :dependent => :delete
end

class Author < ActiveRecord::Base
  attr_accessible :name
  has_one :post

  before_destroy :log_author_removal

  private
    def log_author_removal
      logger.error('Author is getting removed')
    end

end

В консоли:

> Post.first
  Post Load (0.4ms)  SELECT "posts".* FROM "posts" LIMIT 1
 => #<Post id: 5, title: "Post 5", author_id: 3>
> p.delete
  SQL (197.7ms)  DELETE FROM "posts" WHERE "posts"."id" = 5
 => #<Post id: 5, title: "Post 5", author_id: 3> 
> Author.find(3)
  Author Load (0.5ms)  SELECT "authors".* FROM "authors" WHERE "authors"."id" = ? LIMIT 1  [["id", 3]]
 => #<Author id: 3, name: "Author 3"> 

Однако вызов p.destroy удаляет связанного автора.

Я неправильно понял выше цитированное выражение?

Ответы

Ответ 1

Да, вызов delete обычно пропускает все обратные вызовы, которые либо вы, либо рельсы, установленные для уничтожения записи. К ним относятся обратные вызовы типа before_destroy, а также уничтожение связанных записей.

Поэтому, если вы вызываете p.delete, он не будет делать ничего с соответствующими записями.

Когда вы вызываете p.destroy, он будет:

  • Вызвать обратный вызов before_destroy, если он установлен.
  • Удалить объект.
  • Если вы установите :dependent => :delete, он просто удалит объект Author. Если вы установите его на :destroy, он повторит весь этот процесс для объекта автора (обратный вызов и уничтожение связанных записей, если это применимо).
  • Вызвать обратный вызов after_destroy, если он установлен.

Ответ 2

Из того, что я понимаю:

:dependent => :destroy вызывает association.destroy, если вы вызываете destroy на объект.

:dependent => :delete вызывает association.delete, если вы вызываете destroy на объект.

В обоих случаях вы должны вызвать destroy для родительского объекта. Разница заключается в том методе, который называется дочерним объектом. Если вы не хотите запускать фильтры уничтожения на дочернем объекте, используйте :dependent => :delete. Если вы действительно хотите, используйте :dependent => :destroy.

Быстро взглянув на источник здесь: https://github.com/rails/rails/blob/357e288f4470f484ecd500954fd17fba2512c416/activerecord/lib/active_record/associations/builder/belongs_to.rb#L68

Мы видим, что зависимое от вызова будет просто создавать after_destroy в родительской модели, вызывая либо delete, либо destroy дочернего объекта. Но в обоих случаях он создает after_destroy.

Ответ 3

принадлежит к ассоциации поддержка : удалить и : уничтожить для : зависимых. вы можете ссылаться ниже ссылки http://apidock.com/rails/v4.0.2/ActiveRecord/Associations/ClassMethods/belongs_to

вызов delete пропускает все обратные вызовы, такие как before_destroy, а также не удаляет связанные записи для объекта ассоциации.

Пример

class Order < ActiveRecord::Base
has_one :project, :dependent => :delete
has_many :resources, :dependent => :delete
end

class Project < ActiveRecord::Base
belongs_to :order, :dependent => :delete
end

В вышеприведенном коде, если проект был уничтожен, заказ также будет удален, но ресурсы в порядке не удаляются но если мы используем

belongs_to :order, :dependent => :destroy

тогда ресурсы, прикрепленные с заказами, также удаленные при уничтожении проекта.

Ответ 4

 belongs_to :author, :dependent => :delete

Должно быть:    belongs_to: author,: dependent = > : destroy

: destroy и: delete ведут себя по-другому в ActiveRecord, удаляют обход проверки и ассоциации AR, поэтому связанные объекты не удаляются.