重命名哈希中的某个键

时间:2013-10-22 21:08:17

标签: ruby-on-rails ruby hash

我有一个包含2000个条目的列car_details,每个条目都是一个如下所示的信息哈希:

{"capacity"=>"0",
 "wheels"=>"6",
 "weight"=>"3000",
 "engine_type"=>"Diesel",
 "horsepower"=>"350",
 "fuel_capacity"=>"35",
 "fuel_consumption"=>"30"}

有些车有更多细节,有些车更少。我希望在每辆拥有该密钥的汽车上将"fuel_consumption"密钥重命名为"mpg"

3 个答案:

答案 0 :(得分:1)

据我所知,没有简单的方法可以用原始SQL一起更新数据表中的序列化列。我能想到的最好的方法就是做一些事情:

Car.find_each do |car|
  mpg = car.car_details.delete("fuel_consumption")
  car.car_details["mpg"] = mpg if mpg
  car.save
end

这假设您使用的是Active Record,而您的模型被称为“Car”。

答案 1 :(得分:1)

好吧,之前的回答会生成2000个请求,但您可以使用REPLACE函数。 MySQL和PostgreSQL都有,所以它会像:

Car.update_all("car_details = REPLACE(car_details, 'fuel_consumption', 'mpg')")

查看条件的update_all方法。

另请参阅PostgreSQL string functionsMySQL string functions

答案 2 :(得分:1)

@Ivan Shamatov发布的答案非常有效,对于在大型数据库上表现出色尤其重要。

我在jsonb列上的PostgreSQL数据库中进行了尝试。 要使其发挥作用,我们必须同样注意数据类型转换。

例如在这样的User模型上:

User < ActiveRecord::Base {
                   :id => :integer,
           :created_at => :datetime,
           :updated_at => :datetime,
                :email => :string,
           :first_name => :string,
            :last_name => :string,
          :custom_data => :jsonb
}

我的目标是在custom_data jsonb字段中重命名密钥。 例如custom_data哈希来自以下内容的内容:

{
                "foo" => "bar",
           "date" => "1980-07-10"
}

收件人:

{
                "new_foo" => "bar",
             "date" => "1980-07-10"
}

对于所有用户,存在我数据库中的记录。

我们可以执行以下查询:

old_key = 'foo'
new_key = 'new_foo'    
User.all.update_all("custom_data = REPLACE(custom_data::text, '#{old_key}'::text, '#{new_key}'::text)::jsonb")

这只会替换jsonb哈希中的目标键(old_key),而不会更改哈希值或其他哈希键。

请注意::text::jsonb类型的转换!