今天我在rails中遇到了一个bug,这对我来说似乎有点不直观。基本上,在回滚一个事务之后,我在一些关联中仍然有未持久化的模型。我会假设rails在事务回滚时清除这些模型。
基本上我的情况如下:
class Parent < ApplicationRecord
has_many :childs
end
class Child < ApplicationRecord
belongs_to: parent
end
parent = Parent.first
ActiveRecord::Base.transaction do
parent.childs.create!({ :title => 'New' })
raise ActiveRecord::Rollback
end
pp parent.childs
#Here I was expecting parent.childs to be []
#But instead I get [#<Child id: nil>]
我假设create!是www.example.com的 Package 器Class.new。回滚操作会撤消保存操作,但不会撤消新建操作。如果我调用parent.touch或www.example.com,这会引发一个异常parent.save!
我只是想确认我的理解是正确的,在回滚时,我们必须手动清除在事务中编辑的任何关联?
是否有简单的方法来实现这一点,或者我们必须显式地编辑任何修改过的关联,如下所示:
parent.childs = parent.childs.select{|c| c.persisted? }
此外,在我们必须手动清理的情况下,是否有任何方法可以捕获回滚并在救援块中执行清理,或者我们是否必须将事务 Package 在方法中?
1条答案
按热度按时间vybvopom1#
回滚仅通过打开SQL事务并在块的末尾调用
COMMIT
或在块中引发任何异常时调用ROLLBACK
来还原对数据库所做的更改。您正在引发
ActiveRecord::Rollback
,这是在回滚后不会在事务方法之外重新引发的唯一异常。如果要挽救此异常,必须在它到达事务逻辑之前挽救它,然后重新引发它。通常回滚事件会被
ActiveRecord::StatementInvalid
这样的异常触发,回滚后这个异常会被重新引发,这样你就可以捕捉到它并在那里重新加载你的模型。