В качестве примера для круговой dependent: :destroy
проблемы:
class User < ActiveRecord::Base
has_one: :staff, dependent: :destroy
end
class Staff < ActiveRecord::Base
belongs_to :user, dependent: :destroy
end
Если я вызываю user.destroy
, связанный с ним staff
также должен быть уничтожен. И наоборот, вызов staff.destroy
должен также уничтожить связанный user
.
Это отлично работало в Rails 3.x, но поведение изменилось в Rails 4.0 (и продолжается в 4.1), так что цикл формируется и, в конце концов, вы получаете сообщение об ошибке "слишком высокий уровень стека". Одним из очевидных способов решения проблемы является создание пользовательского обратного вызова с помощью before_destroy
или after_destroy
для ручного уничтожения связанных объектов вместо использования механизма dependent: :destroy
. Даже проблема в GitHub, открытая для этого, имела пару человек, рекомендующих это обходное решение.
К сожалению, я даже не могу заставить это обходное решение работать. Это то, что у меня есть:
class User < ActiveRecord::Base
has_one: :staff
after_destroy :destroy_staff
def destroy_staff
staff.destroy if staff and !staff.destroyed?
end
end
Причина, по которой это не работает, заключается в том, что staff.destroyed?
всегда возвращает false
. Таким образом, он образует цикл.