I have a column car_details
with 2000 entries, each of which is a hash of info that looks like this:
{"capacity"=>"0",
"wheels"=>"6",
"weight"=>"3000",
"engine_type"=>"Diesel",
"horsepower"=>"350",
"fuel_capacity"=>"35",
"fuel_consumption"=>"30"}
Some cars have more details, some have less. I want to rename the "fuel_consumption"
key to "mpg"
on every car that has that key.
This is a pretty neat snippet of Ruby that I found to rename a key in a Ruby hash. The #delete method on a hash will return the value of the key provided while removing the item from the hash. The resulting hash gets a new key assigned to the old key's value.
Number sign, also known as the number, pound or hash key, a key on a telephone keypad. For its use in data structure, database and cryptographic applications, see hash function or unique key.
Well, a previous answer will generate 2000 requests, but you can use the REPLACE
function instead. Both MySQL and PostgreSQL have that, so it will be like:
Car.update_all("car_details = REPLACE(car_details, 'fuel_consumption', 'mpg')")
Take a look at the update_all
method for the conditions.
See also PostgreSQL string functions and MySQL string functions.
Answer posted by @Ivan Shamatov works very well and is particular important to have good performances on huge databases.
I tried it with a PostgreSQL database, on a jsonb column. To let it works we have to pay same attention to data type casting.
For example on a User
model like this:
User < ActiveRecord::Base {
:id => :integer,
:created_at => :datetime,
:updated_at => :datetime,
:email => :string,
:first_name => :string,
:last_name => :string,
:custom_data => :jsonb
}
My goal was to rename a key, inside custom_data
jsonb field.
For example custom_data
hash content from:
{
"foo" => "bar",
"date" => "1980-07-10"
}
to:
{
"new_foo" => "bar",
"date" => "1980-07-10"
}
For all users records present into my db.
We can execute this query:
old_key = 'foo'
new_key = 'new_foo'
User.update_all("custom_data = REPLACE(custom_data::text, '#{old_key}'::text, '#{new_key}'::text)::jsonb")
This will only replace the target key (old_key), inside our jsonb hash, without changing hash values or other hash keys.
Note ::text
and ::jsonb
type casting!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With