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. I want to modify a specific key without overwriting the rest of the json.
其中filters字段包含具有嵌套键的json对象。我想修改一个特定的键而不覆盖其余的json。
Currently, the json object stored in filters
looks like
目前,存储在过滤器中的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更新那一个密钥,同时保持其余属性相同?
2 个解决方案
#1
2
which version of rails are you using? 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序列化器,但是一旦你拥有了序列化器,它应该以相同的方式工作,我相信。
#2
0
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,但更新语句将类似于
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关联的新值。
#1
2
which version of rails are you using? 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序列化器,但是一旦你拥有了序列化器,它应该以相同的方式工作,我相信。
#2
0
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,但更新语句将类似于
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关联的新值。