[英]How do I ensure a model always uses a transaction and locks (in Rails)?
[英]How can I ensure that calling #changed? on an instance of an ActiveRecord model after a transaction rolls back returns true?
我在代码中发现了一个问题,其中通过显式引发ActiveRecord :: Rollback来回滚事务块。 在这种情况下,如果模型的实例在回滚之前成功保存在事务中,则它最终会以怪异的状态结束。
这是导致问题的一个简单案例的示例:
record = SomeModel.last
record.attributes = { name: "A New Name"}
SomeModel.transaction do
record.save
raise ActiveRecord::Rollback
end
如果我打电话给record.changed? 交易后,这将返回false。 但是,如果我在交易后调用record.name,则会得到一个“新名称”。 由于某种原因,在这种情况下,记录中的更改没有保存在数据库中,但是ActiveRecord不再将其标识为更改。
在我的实际应用程序中,这在我使用事务的一个区域中引起了问题。 我有代码,如果交易失败,我会尝试使用一些更改的参数再次重试该交易。 如果我重用经历了第一个事务的实例而不重新加载它,则会导致更改未保存,因为它们不会显示为更改。
有人对如何确保实例具有更改并且ActiveRecord仍将这些更改标识为更改有任何建议吗?
ActiveRecord以这种方式工作,因为它以这种方式工作。 我可以想象在回滚事务后从数据库重新加载对象很有用的情况。 我可以想象不会发生的情况。 就像,也许我想保留“新”字段以记录我们向用户显示的值。
您只需要使用其工作方式即可。 由于ActiveRecord不会在事务回滚后重新加载对象,因此您必须自己进行操作。 我想您也可以将代码子类化以执行您想要的操作。
至于肮脏的行为。 它在文档中说,调用保存后,所有脏跟踪行为都会丢失。 事务回滚未保留此信息的过程似乎前后矛盾且令人讨厌。 也许红宝石主义者可以确切地解释为什么必须采用这种方式,尽管从我想象的结构化代码的角度来看这很有意义。 ActiveRecord一直存在。 在这方面,我不会屏息呼吸。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.