简体   繁体   English

Rails模型-更新JSON中的嵌套键/值

[英]Rails Model - Update Nested Key/Value in JSON

I have a model with the following table format: 我有一个具有以下表格格式的模型:

string  "name"
integer "line_id"
json    "filters"

Where the filters field contains a json object with nested keys. 其中filters字段包含带有嵌套键的json对象。 I want to modify a specific key without overwriting the rest of the json. 我想修改一个特定的键而不覆盖json的其余部分。

Currently, the json object stored in filters looks like 当前,存储在filters的json对象看起来像

{
  "ext": {"name": "filter", "id": 3},
  "int": {"name": "numb", "id": 1}
}

I'm trying to update int.name 's value to "remove" without modifying the rest of the json object. 我试图将int.name的值更新为"remove"而不修改json对象的其余部分。

If I do the following, it'll simply overwrite the entire json object instead of modifying that specific key: 如果执行以下操作,它将简单地覆盖整个json对象,而不是修改该特定键:

Model.where("filters->>'int'->>'name' IS NOT NULL").update(
  filters: {
    int: {
      name: "remove"
    }
  }
)

How can I simply update that one key with the path int.name while keeping the rest of the attributes the same? 如何在保持其余属性不变的情况下,简单地使用路径int.name更新该键?

which version of rails are you using? 您正在使用哪个版本的rails? if you are using rails 5, you should be able to 如果您使用的是Rails 5,则应该能够

m = Model.where("filters->>'int'->>'name' IS NOT NULL").first
m.filters['name'] = 'remove'
m.save

this will leave the existing hash keys in place. 这将保留现有的哈希键。

I think with rails 4, you need a json serializer on the field, but should work the same way once you have the serializer, i believe. 我认为在Rails 4上,您需要在现场使用json序列化程序,但我相信,一旦有了序列化程序,就应该以相同的方式工作。

How about something like this 这样的事情怎么样

models = Model.where("filters->>'int'->>'name' IS NOT NULL")
  .each_with_object({}) do |m,obj|
    # credit to mudasobwa for the tap usage 
    obj[m.id] = {filters: m.filters.tap { |h| h['int']['name'] = 'remove' } }
  end 
Model.update(models.keys,models.values)

I have never used a json column so I am unsure if the anticipated value is meant to be JSON or a Hash that will be converted to JSON before insertion but the update statement will be akin to 我从未使用过json列,所以我不确定预期值是JSON还是要在插入之前将其转换为JSON的Hash ,但update语句类似于

Model.update([1],[{
         "ext"=> {"name"=> "filter", "id"=> 3},
         "int"=> {"name"=> "remove", "id"=> 1}
       }])

This uses ActiveRecord::Relation#update where the first Array is the ids to update and the second Array is the new values to associate with those ids. 这使用ActiveRecord::Relation#update ,其中第一个Array是要更新的ID,第二个Array是要与这些ID关联的新值。

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

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