繁体   English   中英

如何确保致电已更改? 事务回滚后在ActiveRecord模型的实例上返回true?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM