2

我试图防止从数据库中删除模型,并且几乎遵循这个guide(请参阅9.2.5.3在before_destroy中练习你的偏执狂)。Rails before_destroy回调数据库变化总是回滚

我有一个简单的模型:

class User < ActiveRecord::Base 
    before_destroy do 
    update_attribute(:deleted_at, Time.current) 
    false 
    end 

,并在控制器:

def destroy 
    @user = User.find(params[:id]) 
    # @user.update!(deleted_at: Time.zone.now) # if I do it here it works 
    @user.destroy # if I also comment this line... 

    render :show 
end 

回调函数被调用和属性被设置,但随后的数据库事务总是被回滚。我遗漏了返回的false模型被删除,因为删除的执行没有停止。

正如你可以在评论中看到的,我可以使它工作,但是我真正想要做的是使用服务对象并将逻辑放在控制器之外。

回答

1

如果您的回调返回false,则该事务将始终回滚。

对于你想要的,你不应该调用你的arel对象上的destroy方法。
相反,使自己的方法,如soft_destroy或类似的东西,并更新您的属性。

为了防止他人在您的arel对象上调用destroy方法,只需添加一个回调引发和异常。

+0

我猜想* false *是原因。感谢您的确认。奇怪的是,这是在一本书中提出的。我会走你提出的路线。谢谢。 – einSelbst 2014-11-04 20:47:19

0

您的模型只是一个对象。如果你真的想改变销毁的概念,请改变它:

def destroy 
    condition ? alt_action : super 
end