【问题标题】:Rails Model - Update Nested Key/Value in JSONRails 模型 - 更新 JSON 中的嵌套键/值
【发布时间】:2018-11-04 00:57:25
【问题描述】:

我有一个表格格式如下的模型:

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

filters 字段包含一个带有嵌套键的 json 对象。我想修改一个特定的键而不覆盖 json 的其余部分。

目前filters中存储的json对象长这样

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

我正在尝试将int.name 的值更新为"remove",而不修改json 对象的其余部分。

如果我执行以下操作,它将简单地覆盖整个 json 对象,而不是修改该特定键:

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

我怎样才能简单地使用路径int.name 更新那个键,同时保持其余属性相同?

【问题讨论】:

    标签: ruby-on-rails json ruby postgresql


    【解决方案1】:

    您使用的是哪个版本的导轨?如果您使用的是 rails 5,您应该能够

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

    这将保留现有的哈希键。

    我认为使用 rails 4,您需要在现场使用 json 序列化程序,但我相信,一旦您拥有序列化程序,应该以相同的方式工作。

    【讨论】:

    • 这就是我最终做的事情,而且效果很好!我希望有一个 API,但毕竟看起来不像
    【解决方案2】:

    这样的事情怎么样

    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)
    

    我从未使用过 json 列,因此我不确定预期值是 JSON 还是 Hash,在插入之前将转换为 JSON,但更新语句将类似于

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

    这使用ActiveRecord::Relation#update,其中第一个Array 是要更新的ID,第二个Array 是与这些ID 关联的新值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      相关资源
      最近更新 更多