: 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, поэтому связанные объекты не удаляются.
Ответ 5
association_to не может поддерживать : delete для : depedent. Он поддерживает только : destroy. См. Ссылку http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html.