Before_destroy и зависимый уничтожить не стрельбу
У меня есть следующие ассоциации моделей:
class Slider < ActiveRecord::Base
has_one :featured_happening, :as => :featured_item, :dependent => :destroy
before_destroy :destroy_featured_happening
after_create :create_featured_happening
end
class FeaturedHappening < ActiveRecord::Base
belongs_to :featured_item, :polymorphic => true
end
Когда я уничтожаю объект Slider
, я думал, что dependent => :destroy
автоматически уничтожит featured_item
, но это не так.
Контроллер ползунка
def destroy
slider = Slider.find(params[:id])
slider.delete
render(:status => :ok, :nothing => true )
end
Итак, я попробовал обратный вызов с before_destroy
, чтобы вручную удалить featured_item
, когда объект слайдера уничтожен и ничего не вызвано.
Как я могу удалить featured_item
при удалении объекта слайдера? Использование Rails 3.2.
Ответы
Ответ 1
Вы только что заметили разницу между delete
и destroy
. В контроллере вы вызываете
slider.delete
который просто выполнит SQL delete
, но не вызовет никаких обратных вызовов. Поэтому в обычных случаях вы хотите использовать destroy
. Он будет извлекать объект (при необходимости), вызывать обратные вызовы, включая рекурсивные разрушения, и только затем удаляет объект из базы данных.
См. документацию для delete и destroy для получения дополнительной информации.
Ответ 2
Убедитесь, что вы вызываете Slider#destroy
, чтобы активировать обратные вызовы. Slider#delete
просто удалит запись, не вызывая их.
Ответ 3
class Slider < ActiveRecord::Base
has_one :featured_happening, :dependent => :destroy
end
class FeaturedHappening < ActiveRecord::Base
belongs_to :featured_item
end
Если ваш код был прост, как указано выше, в котором есть простые отношения. Затем с удалением слайдера функция Happing будет удалена с удалением ползунка. Но в вашем случае отношения являются полиморфными. В таблице функций happing в DB abject_id будет идентификатором ползунка или может быть другим классом. Поэтому зависимый: уничтожить не работает. Поэтому вам нужно удалить его с помощью обратного вызова before_destroy, в котором вы сначала извлекаете записи, а затем уничтожаете их.