Skip to content

Instantly share code, notes, and snippets.

@danielevans
Created June 6, 2012 19:23
Show Gist options
  • Save danielevans/2884087 to your computer and use it in GitHub Desktop.
Save danielevans/2884087 to your computer and use it in GitHub Desktop.
Converting Serialized YAML to Serialized JSON in Rails models
class Medium < ActiveRecord::Base
serialize :payload, JSON
end
class Medium < ActiveRecord::Base
serialize :payload
end
# create a facade model to avoid validations and other shenanigans
faux_medium = Class.new ActiveRecord::Base
faux_medium.table_name = "media"
# only loading the id and the payload helps avoid certain problems and speeds up the conversion
faux_medium.select([:id, :payload]).find_in_batches do |media|
media.each do |medium|
begin
# manually encode to JSON because of the facade class
medium.payload = YAML.load(medium.send(:attribute, :payload)).to_json
medium.save!
rescue Exception => e
puts "Could not fix medium #{medium.id} for #{e.message}"
end
end
end
hash = { "A" => "B", "C" => "D", "E" => "F", "G" => "H", "I" => { "J" => "K", "L" => "M", "N" => "O", "P" => "Q", "R" => "S" } }
yaml = hash.to_yaml
json = hash.to_json
yaml_time = Benchmark.realtime do
1000.times do
YAML.load yaml
end
end # => 5.85665
json_time = Benchmark.realtime do
1000.times do
JSON.load json
end
end # => 0.012307
@Confusion
Copy link

Thanks, I had forgotten that you can very easily define a new class for the same table to do neat tricks like this one.

When doing these steps in a Rails console, you need to use

faux_medium = Class.new ActiveRecord::Base do
  self.table_name = "media"
end

otherwise the first line results in an error, because it attempts to show something sensible for the new Class in the console and that attempt trigger an error, because no table name is set yet.

@danielpuglisi
Copy link

Thanks, very useful! 👍

@yetrun
Copy link

yetrun commented Sep 29, 2022

Why use medium.send(:attribute, :payload) while not use medium.payload directly? My execution raises a error which said "undefined method `asstribute` for the class faux_medium".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment