重命名哈希中的某个键

问题描述 投票:4回答:3

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

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

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

ruby-on-rails ruby hash
3个回答
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,并且您的模型称为“汽车”。


2
投票

嗯,先前的答案将生成2000个请求,但是您可以改用REPLACE函数。 MySQL和PostgreSQL都有,所以就像:

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

查看条件的update_all方法。

另请参见update_allPostgreSQL string functions


1
投票

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

我在jsonb列上的PostgreSQL数据库中尝试过。为了使其工作,我们必须同样注意数据类型转换。

例如,在像这样的MySQL string functions模型上:

User

我的目标是在User < ActiveRecord::Base { :id => :integer, :created_at => :datetime, :updated_at => :datetime, :email => :string, :first_name => :string, :last_name => :string, :custom_data => :jsonb } jsonb字段内重命名密钥。例如custom_data哈希来自以下内容:

custom_data

至:

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

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

我们可以执行此查询:

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

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

注意old_key = 'foo' new_key = 'new_foo' User.all.update_all("custom_data = REPLACE(custom_data::text, '#{old_key}'::text, '#{new_key}'::text)::jsonb") ::text类型转换!

© www.soinside.com 2019 - 2024. All rights reserved.