ActiveRecord serialize using JSON instead of YAML ActiveRecord serialize using JSON instead of YAML json json

ActiveRecord serialize using JSON instead of YAML


In Rails 3.1 you can just

class Form < ActiveRecord::Base  serialize :column, JSONend

Hope that helps


In Rails 3.1 you can use custom coders with serialize.

class ColorCoder  # Called to deserialize data to ruby object.  def load(data)  end  # Called to convert from ruby object to serialized data.  def dump(obj)  endendclass Fruits < ActiveRecord::Base  serialize :color, ColorCoder.newend

Hope this helps.

References:

Definition of serialize:https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L556

The default YAML coder that ships with rails:https://github.com/rails/rails/blob/master/activerecord/lib/active_record/coders/yaml_column.rb

And this is where the call to the load happens:https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/read.rb#L132


Update

See mid's high rated answer below for a much more appropriate Rails >= 3.1 answer. This is a great answer for Rails < 3.1.

Probably this is what you're looking for.

Form.find(:first).to_json

Update

1) Install 'json' gem:

gem install json

2) Create JsonWrapper class

# lib/json_wrapper.rbrequire 'json'class JsonWrapper  def initialize(attribute)    @attribute = attribute.to_s  end  def before_save(record)    record.send("#{@attribute}=", JsonWrapper.encrypt(record.send("#{@attribute}")))  end  def after_save(record)    record.send("#{@attribute}=", JsonWrapper.decrypt(record.send("#{@attribute}")))  end  def self.encrypt(value)    value.to_json  end  def self.decrypt(value)    JSON.parse(value) rescue value  endend

3) Add model callbacks:

#app/models/user.rbclass User < ActiveRecord::Base    before_save      JsonWrapper.new( :name )    after_save       JsonWrapper.new( :name )    def after_find      self.name = JsonWrapper.decrypt self.name    endend

4) Test it!

User.create :name => {"a"=>"b", "c"=>["d", "e"]}

PS:

It's not quite DRY, but I did my best. If anyone can fix after_find in User model, it'll be great.