我在数据库中有一些jsonb,我想动态地写一个属性,我知道该属性的路径,但是它可以是任何深度和任何属性名称。
我知道属性的路径,但是我发现编写这种动态性的唯一方法是使用eval()
。
eval("self.some_json_column['an_array'][10]['a_different_array'][5]['color'] = 'blue'")
self.save
所以我知道深度和数组索引,但是它可以是任何深度或索引。我可以构建字符串并将其传递到eval()
但是我知道eval()
是最后一种情况,不知道是否可以构建路径并在不使用eval()
的情况下动态写入(在这种情况下为color json属性)
谢谢。
答案 0 :(得分:4)
您可以减少通过Hash
返回的self.some_json_column
的方式
*path, target = ['an_array',10,'a_different_array',5,'color']
node = path.reduce(self.some_json_colum, &:[])
node[target] = 'blue' if node
如果路径的任何部分不正确,这将没有错误处理
您还可以根据红宝石版本来研究dig
node = self.some_json_column.dig(*path)
node[target] = 'blue' if node
如果路径的任何部分不匹配,它将返回nil
示例:
h = {
'an_array' => [0,1,2,3,4,5,6,7,8,9,
{'a_different_array' => [1,2,3,4,5, {'color' => 'orange'}]}
]
}
*path,target = ['an_array',10,'a_different_array',5,'color']
h.dig(*path)[target] = 'blue'
h
#=> {"an_array"=>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
# {"a_different_array"=>[0, 1, 2, 3, 4,
# {"color"=>"blue"}
# ]}
# ]}