Rails before_destroy回调数据库更改总是回滚

时间:2014-11-04 13:06:20

标签: ruby-on-rails postgresql callback rails-activerecord activemodel

我试图阻止从数据库中删除模型,并且几乎遵循这个guide(参见 9.2.5.3使用before_destroy运行你的偏执狂)来自Rails 4书

我有一个简单的模型:

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返回的模型被删除,因为删除的执行没有停止。

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

2 个答案:

答案 0 :(得分:1)

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

对于你想要的东西,你不应该在你的arel对象上调用destroy方法 相反,请创建自己的方法,例如soft_destroy或类似的方法,然后更新您的属性。

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

答案 1 :(得分:0)

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

def destroy
  condition ? alt_action : super
end