before_destroy和dependent destroy不会解雇

时间:2012-03-26 03:28:22

标签: ruby-on-rails activerecord callback

我有以下模型关联:

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。

3 个答案:

答案 0 :(得分:20)

您刚观察到deletedestroy之间的区别。在你的控制器中你打电话

slider.delete

只执行SQL DELETE但不会调用任何回调。这就是为什么在正常情况下你想要使用destroy。它将获取对象(如果需要),调用包括递归销毁的回调,然后从数据库中删除该对象。

有关详细信息,请参阅deletedestroy的文档。

答案 1 :(得分:4)

确保您正在调用Slider#destroy以触发回调。 Slider#delete只会删除记录而不会调用它们。

答案 2 :(得分:0)

class Slider < ActiveRecord::Base
  has_one :featured_happening,  :dependent => :destroy  
end

class FeaturedHappening < ActiveRecord::Base
  belongs_to :featured_item
end

如果您的代码很简单,就像上面那样有简单的关系。然后删除滑块,删除滑块将删除Feature Happing。但在你的情况下,这种关系是多态的。在DB中的功能happing表中,abject_id将是滑块的id或者可能是其他类。因此依赖:破坏不工作。因此,您需要使用before_destroy回调删除它,在该回调中首先检索记录然后销毁它们