在Rails 5中,我实现了一系列关系,这些关系在保存一个复杂模型时会导致鸡蛋问题。 (需要ID来关联对象,但在它们被保存之后才会存在。)
我需要以困难的方式创建和保存对象,但如果保存失败,我需要自己清理,所以我不会得到一个装满空对象的数据库。
从模型中,当且仅当保存失败时,如何确保清理代码运行?标准的回调列表似乎并不包括这种情况,除非我遗漏了一些东西。
答案 0 :(得分:4)
模型回调是Rails中过度使用和滥用最多的功能之一。它们非常适合在模型的生命周期中添加简单的回调,但是在它们被触发时非常难以控制(比如在测试中它们会减慢一切),或者进入流程以添加应用程序逻辑。
如果您的回调影响的次数超过定义回调的模型,那么您应该使用回调重新考虑这一点。
在这种情况下,您最想要的是transaction:
A.transaction do
begin
a = A.create!(some_params)
a.bs.create!(some_other_params)
rescue ActiveRecord::RecordInvalid
a
end
end
这将操作包装在数据库事务中,如果任一操作失败,则回滚该数据库事务 - 保持数据库不变。
您可以在控制器中对此进行内联,也可以将其包装在service object。
中