Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 返回false并在保存回调后回滚_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails 返回false并在保存回调后回滚

Ruby on rails 返回false并在保存回调后回滚,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,在ActiveRecord模型中,在保存回调之后,我需要回滚事务并返回false def after_save_callback if mycondition? raise ActiveRecord::Rollback end end 此回调回滚事务,但不回滚mymodel.save!返回true。如何使其返回false并回滚?我认为在保存后,您不能使用执行此操作,您应该查看保存前后的: def around_save ActiveRecord::Base.transact

在ActiveRecord模型中,在保存回调之后,我需要回滚事务并返回false

def after_save_callback
  if mycondition?
    raise ActiveRecord::Rollback
  end
end

此回调回滚事务,但不回滚mymodel.save!返回true。如何使其返回false并回滚?

我认为在保存后,您不能使用
执行此操作,您应该查看保存前后的

def around_save
  ActiveRecord::Base.transaction do
    yield # calls the actual save method
    raise ActiveRecord::Rollback if my_condition?
  end
end
所以。。。我认为保存已经在事务块上,所以不需要添加额外的ActiveRecord::Base.transaction do块,因为回滚不会向上传播

因此,如果您想在收益之前或之后回滚,则需要删除该内部事务

def around_save
  #ActiveRecord::Base.transaction do
    raise ActiveRecord::Rollback # this will actually ROLLBACK
    yield # calls the actual save method
    raise ActiveRecord::Rollback # this will actually ROLLBACK
  # end
end

编辑:阅读我写的内容。。。现在似乎很难理解。要点是:如果要使用
aroud\u save
,请不要再次使用
ActiveRecord::Base.transaction
像上一个示例一样)因为rails将使用is own
ActiveRecord::Base.transaction
来包装对
的调用,所以当您
启动ActiveRecord::Rollback
时,您只回滚最内部的事务,因此您可以以额外的结果和部分保存结束(就像第一个示例中的FAIL).

如果您想在保存
回调后在
中中止保存,您应该

raise ActiveRecord::RecordInvalid.new(self)
而不是

raise ActiveRecord::Rollback
这不仅会回滚事务(作为
保存
创建
的一部分,回调总是发生在可能的隐式事务中),而且还会导致
保存
返回

下面是一篇更详细的文章:

Rails在事务中包装
Model#save
。您不应该在around_save钩子中打开第二个事务。相反,您应该只启动
ActiveRecord::Rollback
raise ActiveRecord::Rollback