简体   繁体   English

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

[英]How can I ensure that calling #changed? on an instance of an ActiveRecord model after a transaction rolls back returns true?

I found an issue in my code where a transaction block is rollback by explicitly raising an ActiveRecord::Rollback. 我在代码中发现了一个问题,其中通过显式引发ActiveRecord :: Rollback来回滚事务块。 In this case if an instance of a model saves successfully in the transaction before the rollback it ends up in a weird state. 在这种情况下,如果模型的实例在回滚之前成功保存在事务中,则它最终会以怪异的状态结束。

Here is an example of a simple case that causes the issue: 这是导致问题的一个简单案例的示例:

record = SomeModel.last
record.attributes = { name: "A New Name"}

SomeModel.transaction do 
  record.save
  raise ActiveRecord::Rollback
end

If I called record.changed? 如果我打电话给record.changed? after the transaction this will return false. 交易后,这将返回false。 However, if I call record.name after the transaction I would get a "A New Name". 但是,如果我在交易后调用record.name,则会得到一个“新名称”。 For some reason in this case the record has changes that were not persisted in the database, but ActiveRecord is not identifying these as changes anymore. 由于某种原因,在这种情况下,记录中的更改没有保存在数据库中,但是ActiveRecord不再将其标识为更改。

In my real-world application this is causing an issue in one area I use transactions. 在我的实际应用程序中,这在我使用事务的一个区域中引起了问题。 I have code where if a transaction fails I attempt to retry the transaction again with some changed parameters. 我有代码,如果交易失败,我会尝试使用一些更改的参数再次重试该交易。 If I reuse the instance that went through the first transaction without reloading it this results in the changes not being saved since they don't appear as changes. 如果我重用经历了第一个事务的实例而不重新加载它,则会导致更改未保存,因为它们不会显示为更改。

Does anyone have any suggestions how to ensure that the instance has the changes and ActiveRecord still identifies these as changes? 有人对如何确保实例具有更改并且ActiveRecord仍将这些更改标识为更改有任何建议吗?

ActiveRecord works this way, because it works this way. ActiveRecord以这种方式工作,因为它以这种方式工作。 I can imagine scenarios in which it would be useful to reload the object from the database after rolling back a transaction. 我可以想象在回滚事务后从数据库重新加载对象很有用的情况。 I can imagine scenarios in which it would not. 我可以想象不会发生的情况。 Like, maybe I want to preserve the "new" fields to log the values our to show them to the user. 就像,也许我想保留“新”字段以记录我们向用户显示的值。

You just need to work with the way it works. 您只需要使用其工作方式即可。 Since ActiveRecord doesn't reload the object after a transaction rollback you have to do it yourself. 由于ActiveRecord不会在事务回滚后重新加载对象,因此您必须自己进行操作。 I suppose you could also subclass the code to do what you want. 我想您也可以将代码子类化以执行您想要的操作。

As for the dirty behavior. 至于肮脏的行为。 It says in the docs that all the dirty tracking behavior is lost after calling save. 它在文档中说,调用保存后,所有脏跟踪行为都会丢失。 That the transaction rollback doesn't preserve this information does seem inconsistent and annoying. 事务回滚未保留此信息的过程似乎前后矛盾且令人讨厌。 Perhaps a rubyist can explain exactly why it has to be this way, though it makes sense from the way I imagine the code to be structured. 也许红宝石主义者可以确切地解释为什么必须采用这种方式,尽管从我想象的结构化代码的角度来看这很有意义。 ActiveRecord has been around forever. ActiveRecord一直存在。 I wouldn't hold my breath for it to work differently in this regard. 在这方面,我不会屏息呼吸。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保模型始终使用事务和锁(在 Rails 中)? - How do I ensure a model always uses a transaction and locks (in Rails)? 如何从ActiveRecord的事务中排除模型? - How do I exclude a model from a transaction in ActiveRecord? 如何确保ActiveRecord将更改保存到数据库 - How can I ensure that ActiveRecord is saving changes to the database 如何显示所有_changed? ActiveRecord模型的方法 - How do I display all _changed? methods for an ActiveRecord model 如何检查ActiveRecord的after_save回调中是否更改了关联的记录数组? - How can I check whether an associated array of records was changed in after_save callback for ActiveRecord? 如何为ActiveRecord模型设置model.changed? - How to set model.changed for an ActiveRecord model? 在rails中,如何在与其他模型连接后获取模型的所有参数,获得ActiveRecord :: Relation,其中count的方法返回一个数字 - in rails, how can I get all parameters of a model after joining with other models, get an ActiveRecord::Relation which count's method returns a number 如何确保只有一个带有mongoid的已保存模型实例? - How do I ensure that there is only one instance of saved model with mongoid? 如何使该ActiveRecord无表模型生效? - How can I inizialize that ActiveRecord Tableless Model? 如何在Rails / ActiveRecord中的事务之外执行数据库操作 - How can I execute a Database Operation outside of a transaction in Rails / ActiveRecord
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM