在 Ruby on Rails 中,有没有比使用 eval() 动态访问此 json 更好的方法?

In Ruby on Rails is there a better way than using eval() to accses this jsonb dynamically?

我在数据库中有一些 jsonb,我想动态写入属性,我知道属性的路径,但它可以是任何深度和任何属性名称。

我知道属性的路径,但是我发现写这个 dynamiaclly 的唯一方法是 eval()

eval("self.some_json_column['an_array'][10]['a_different_array'][5]['color'] = 'blue'")
self.save

所以我知道深度和数组索引,但它可以是任何深度或索引。我可以构建字符串并将其传递到 eval()

但是我知道 eval() 是最后一种情况,并且想知道是否可以在不使用 [=13 的情况下动态构建路径和写入(在本例中是颜色 json 属性) =]

谢谢。

您可以减少通过 Hash 的方式,该 Hashself.some_json_column

编辑 return
*path, target = ['an_array',10,'a_different_array',5,'color']
node = path.reduce(self.some_json_colum, &:[])
node[target] = 'blue' if node  

如果路径的任何部分不正确,这没有错误处理

您还可以根据 ruby 版本查看 dig

node = self.some_json_column.dig(*path)
node[target] = 'blue' if node

如果路径的任何部分不匹配,这将 return 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"}
#     ]}
#   ]}