Gab*_*iel 7 ruby ruby-on-rails activemodel
我正在使用ActiveModel::Dirty来跟踪表单中所做的更改。现在一切都按我的预期进行。对于像电话号码这样在表单中出现破折号的东西,我只需对其进行格式化,然后电话号码就不会出现在.changed
预期行为的列表中。
但是,我遇到了一个问题,即我在配置文件模型中使用 jsonb 字段。所以问题是 ActiveModel 会将 JSONB 字段列为已更改,即使我专门对其进行格式化以匹配它之前的外观。这不是预期的行为。更奇怪的是,我的另一个 JSONB 专栏并没有经历这种疯狂。
我遇到问题的 JSONB 字段看起来像这样,
store_accessor :user_details, :names, :other_field
store_accessor :bank_details, :bank_city, :bank_name
user_details
并且bank_details
是 jsonb 列。需要注意的一些事情:names 是一个数组,other_field 是一个字符串。bank_city 和bank_name 是字符串。
任何人都可以深入了解为什么 :user_details 特别是在解决这个问题,而不是 :bank_details JSON 列?
我怀疑这可能是由于我在 :user_details 中使用了一个数组,并且我怀疑 ActiveModel 源代码中的某处发生了比较,但也许我错了?
编辑:我发现这肯定是因为我使用数组来表示:名称。我将其更改为字符串,它不再认为 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.
Run Code Online (Sandbox Code Playgroud)
在 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 问题并抱怨这不起作用。
归档时间: |
|
查看次数: |
2019 次 |
最近记录: |