Ruby on rails 保存失败时的rails回调

Ruby on rails 保存失败时的rails回调,ruby-on-rails,ruby,activerecord,ruby-on-rails-5,Ruby On Rails,Ruby,Activerecord,Ruby On Rails 5,在Rails 5中,我实现了一系列关系,在保存一个复杂模型时,这些关系会导致鸡和蛋的问题。(需要ID来关联对象,但在保存对象之前ID不存在。) 我需要以艰难的方式创建和保存对象,但如果保存失败,我需要自己清理,这样我就不会得到一个满是空对象的数据库 从模型来看,如何确保在且仅在保存失败时运行清理代码?标准的回调列表似乎不包括这种情况,除非我遗漏了一些东西。模型回调是Rails中最被过度使用和误用的特性之一。它们非常适合在模型的生命周期中添加简单的回调,但很难控制何时启动它们(比如在测试中,它们会

在Rails 5中,我实现了一系列关系,在保存一个复杂模型时,这些关系会导致鸡和蛋的问题。(需要ID来关联对象,但在保存对象之前ID不存在。)

我需要以艰难的方式创建和保存对象,但如果保存失败,我需要自己清理,这样我就不会得到一个满是空对象的数据库


从模型来看,如何确保在且仅在保存失败时运行清理代码?标准的回调列表似乎不包括这种情况,除非我遗漏了一些东西。

模型回调是Rails中最被过度使用和误用的特性之一。它们非常适合在模型的生命周期中添加简单的回调,但很难控制何时启动它们(比如在测试中,它们会减慢速度),也很难利用流程来添加应用程序逻辑

如果您的回调比定义回调的模型影响更大,那么这是一个很好的迹象,您应该重新考虑使用回调

在这种情况下,您最可能想要的是:

这会将该操作包装在数据库事务中,如果其中一个操作失败,该数据库事务将回滚-保持数据库不变


您可以将其内联到控制器中,也可以将其包装到一个组件中。

模型回调是Rails中最被过度使用和误用的特性之一。它们非常适合在模型的生命周期中添加简单的回调,但很难控制何时启动它们(比如在测试中,它们会减慢速度),也很难利用流程来添加应用程序逻辑

如果您的回调比定义回调的模型影响更大,那么这是一个很好的迹象,您应该重新考虑使用回调

在这种情况下,您最可能想要的是:

这会将该操作包装在数据库事务中,如果其中一个操作失败,该数据库事务将回滚-保持数据库不变


您可以将其内联到控制器中,也可以将其包装到一个文件中。

我不会对此使用回调。我将在事务中包装一系列create/save语句。如果任何操作失败,事务将自动回滚。只有在使用
.create时,事务才会回滚
。保存
虽然他们会在
时引发错误。create
save
不会这样做。@max您仍然可以自由地检查一切是否正常,并在任何问题上手动执行
回滚操作。
是的@mudasobwa,但这不是自动的:)您能给出一个模型定义的示例吗?我不会为此使用回调。我将在事务中包装一系列create/save语句。如果任何操作失败,事务将自动回滚。只有在使用
.create时,事务才会回滚
。保存
虽然他们会在
时引发错误。create
save
不会这样做。@max您仍然可以自由地检查一切是否正常,并在任何问题上手动
引发回滚
。是的@mudasobwa,但这不是自动的:)您能给出一个模型定义的示例吗?服务对象可能是一种方法。“模型回调是Rails中最被过度使用和误用的特性之一。“这一整天!你赢得了互联网。我喜欢你的风格。在过去,我一直避免过度使用回调,甚至在特别糟糕的代码库中实现观察者模式,以避免回调循环和其他回调问题。在这里,当我使用ActiveAdmin时,我觉得自己与回调绑定在一起,但理论上我可以重写save方法并将其委托给另一个对象。服务对象可能就是解决方法。“模型回调是Rails中最被过度使用和误用的功能之一。”这一整天都在发生!你赢得了互联网。我喜欢你的风格。在过去,我一直避免过度使用回调,甚至在特别糟糕的代码库中实现观察者模式,以避免回调循环和其他回调问题。当我使用ActiveAdmin时,我觉得这里绑定了回调,但理论上我可以重写save方法并委托给另一个对象。
A.transaction do 
   begin 
     a = A.create!(some_params)
     a.bs.create!(some_other_params)
   rescue ActiveRecord::RecordInvalid
     a
   end
end