在Ruby on Rails中,有没有比使用eval()动态地控制此jsonb更好的方法了?

时间:2019-05-10 18:58:39

标签: ruby-on-rails json ruby eval jsonb

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

我知道属性的路径,但是我发现编写这种动态性的唯一方法是使用eval()

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

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

但是我知道eval()是最后一种情况,不知道是否可以构建路径并在不使用eval()的情况下动态写入(在这种情况下为color json属性)

谢谢。

1 个答案:

答案 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"}
#     ]}
#   ]}