更新属性后ActiveRecord不保存
我想知道在这里是否有一些我不理解的东西,或者我是否遇到过ActiveRecord(4.1.1)中的错误。
我有一个数据库,里面只有一个属性,一个JSON字段。 我拿一个并尝试更新它。
test = Submission.find(1) test.update_attribute('json_data',similar_but_different_json(test.json_data))
我们假设方法similar_but_different_json
对该JSON进行了一次小的更新。 在我的情况下,我正在修复由损坏的表单创建的一些数据错误。
执行此操作时,我没有收到任何错误,我在控制台中显示提交但未提交数据并返回true
。
为了实际更新记录,我必须这样做。
test = Submission.find(1) old_json_data = test.json_data test.json_data = "" test.json_data = similar_but_different_json(old_json_data) test.save
似乎正在发生的事情是ActiveRecord没有确定已经进行了必须保存的更改。 这可能是为什么将字段设置为空字符串然后返回JSON允许记录保存?
will_change!
您还可以使用:
test.json_data_will_change! # Goes before the save.
这将告诉ActiveModel属性json_data
已经改变(即它是脏的 ←那里有一个笑话)并将在保存时正确更新值。
有关更多详细信息,请参阅Rails未保存已更改的属性 。
我不明白为什么对象没有标记为脏。 解决方法是使用update_columns
:
test.update_columns(json_data: similar_but_different_json(test.json_data))
它将直接在DB中执行UPDATE查询,无需任何validation,脏检查等…但json_data
字段不能是只读的。
ActiveModel(通过4.1.1)无法跟踪属性上的“内联”修改。
你的’similar_but_different_json’方法可能会对字符串进行内联修改。
只需复制字符串,然后再修改它。
test = Submission.find(1) test_json_data_duplicate = test.json_data.dup test.update_attribute('json_data',similar_but_different_json(test_json_data_duplicate))
你什么时候……
test.json_data = ""
… ActiveModel可以捕获更改,因为您将其设置为恰好为空的新String对象。 因此,当您调用update_attribute时,模型已经知道该属性已更改。
如果您尝试以内联方式清空字符串,那么您的技巧将无效。
test = Submission.find(1) old_json_data = test.json_data test.json_data.clear # Instead of test.json_data = "" test.json_data = similar_but_different_json(old_json_data) test.save
::加载ActiveModel脏