Tob*_*ede 55 serialization activerecord json yaml ruby-on-rails
I have a model that uses a serialized column:
class Form < ActiveRecord::Base
serialize :options, Hash
end
Run Code Online (Sandbox Code Playgroud)
Is there a way to make this serialization use JSON instead of YAML?
Jus*_* L. 157
在Rails 3.1中你可以
class Form < ActiveRecord::Base
serialize :column, JSON
end
Run Code Online (Sandbox Code Playgroud)
希望有所帮助
bal*_*alu 58
在Rails 3.1中,您可以使用自定义编码器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)
end
end
class Fruits < ActiveRecord::Base
serialize :color, ColorCoder.new
end
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
参考文献:
定义serialize
:https:
//github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L556
随rails提供的默认YAML编码器:https: //github.com/rails/rails/blob/master/activerecord/lib/active_record/coders/yaml_column.rb
这就是调用的地方load
:https:
//github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/read.rb#L132
St.*_*and 11
更新
请参阅下面的mid评分较高的答案,以获得更合适的Rails> = 3.1答案.这是Rails <3.1的一个很好的答案.
可能这就是你要找的东西.
Form.find(:first).to_json
Run Code Online (Sandbox Code Playgroud)
更新
1)安装'JSON' 宝石:
gem install json
Run Code Online (Sandbox Code Playgroud)
2)创建JsonWrapper类
# lib/json_wrapper.rb
require '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
end
end
Run Code Online (Sandbox Code Playgroud)
3)添加模型回调:
#app/models/user.rb
class User < ActiveRecord::Base
before_save JsonWrapper.new( :name )
after_save JsonWrapper.new( :name )
def after_find
self.name = JsonWrapper.decrypt self.name
end
end
Run Code Online (Sandbox Code Playgroud)
4)测试一下!
User.create :name => {"a"=>"b", "c"=>["d", "e"]}
Run Code Online (Sandbox Code Playgroud)
它不是很干,但我尽了最大努力.如果任何人都可以修复after_find
的User
模型,这将是巨大的.
我的要求在这个阶段不需要大量的代码重用,所以我的提炼代码是上述答案的变体:
require "json/ext"
before_save :json_serialize
after_save :json_deserialize
def json_serialize
self.options = self.options.to_json
end
def json_deserialize
self.options = JSON.parse(options)
end
def after_find
json_deserialize
end
Run Code Online (Sandbox Code Playgroud)
干杯,到底相当容易!