ruby-on-rails - ActiveModel::Dirty 和 JSON 字段

标签 ruby-on-rails ruby activemodel

我正在使用 ActiveModel::Dirty跟踪表单中所做的更改。现在一切都如我所料。对于像电话号码这样的东西,当在表单中时,我只是简单地格式化它们,然后电话号码将不会出现在 .changed 列表中,这是预期的行为。

但是我遇到了一个问题,我在我的 Profile 模型中使用了一个 jsonb 字段。所以问题是 ActiveModel 会将 JSONB 字段列为已更改,即使我专门对其进行格式化以匹配它之前的外观。这不是预期的行为。更奇怪的是,我拥有的另一个 JSONB 专栏并没有经历过这种疯狂。

我遇到问题的 JSONB 字段看起来像这样 store_accessor :user_details, :names, :other_field store_accessor :bank_details, :bank_city, :bank_name user_detailsbank_details 是 jsonb 列。 需要注意的一些事情:names 是一个数组,other_field 是一个字符串。 bank_city 和 bank_name 是字符串。

任何人都可以深入了解为什么 :user_details 特别是在努力解决这个问题而不是 :bank_details JSON 列吗?

我怀疑这可能是因为我在 :user_details 中使用了一个数组,我怀疑比较在 ActiveModel 源代码的某处被忽略了,但也许我错了?

编辑: 我发现这肯定是因为我正在为 :names 使用数组。我将其更改为字符串,它不再认为 JSON 列已更改。打算深入研究 ActiveModel 源代码,看看我是否能找到原因。

编辑#2: 出于某种原因,我认为我什么都不做就解决了这个问题,但我是个傻瓜,我意识到我已经删除了表格中的一些东西。所以这个问题对我来说仍然没有解决。任何见解都会令人惊叹。我无法通过查看 ActiveModel::Dirty 源代码来弄清楚为什么会这样。我不完全确定在哪里看。打算加入 byebugs 以查看是否有帮助。

编辑#3: 重复此问题的步骤

创建一个带有 JSONB 列的 Rails 模型。 设置商店访问器,您只需要一个即可。 使用验证器或格式化程序将其默认设置为空数组。 为您的模型提供 ActiveModel::Dirty 包含。 运行 Rails 控制台。 运行以下命令。 假设 user_details 是 JSONB 列,它的存储访问器是名称。

  a = Profile.user_details
  a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
  a.changed # This will show that user_details has changed which is correct
  a.names = []
  a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.

最佳答案

在 Rails Github 上打开一个问题后,我得到了回复 https://github.com/rails/rails/issues/34537#issuecomment-442265161

更改是通过 json、jsonb、hstore 和序列化属性类型的属性强制执行的。源代码在这里:https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181

我遇到这个问题的原因是我不再尝试尝试,因为我正在从事的项目不会使用 ActiveModel::Dirty 并且不会尝试跟踪更改的方式我正在尝试这样做。

因此,所有遇到此问题的后代都祝你好运,并随时进入该 github 问题并提示这不起作用。

关于ruby-on-rails - ActiveModel::Dirty 和 JSON 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53490150/

相关文章:

ruby-on-rails - rails 、yml 和多行

ruby-on-rails - 设计 before_authenticate?

arrays - Ruby 将修改后的数组保存在变量中而不更改原始数组

ruby-on-rails - ActiveModel 是否有包含 "update_attributes"方法的模块?

ruby-on-rails - Rails 多对一关联

mysql - rake 数据库 :multi:migrate DATABASE=configuration error with JRuby, mysql,riak

ruby-on-rails - Group by 和 order by 在 Rails 中有很多直通模型

sql - 在防止 SQL 注入(inject)时,PG::Connection#exec_params 是否与使用准备好的语句相同?

ruby-on-rails - Rails : . create 使 :id 的自定义值无效

ruby-on-rails - ActiveModel 方法属性 "_was"的用途是什么?