YAML 대신 JSON을 사용하여 ActiveRecord 직렬화
직렬화 된 열을 사용하는 모델이 있습니다.
class Form < ActiveRecord::Base
serialize :options, Hash
end
이 직렬화가 YAML 대신 JSON을 사용하도록하는 방법이 있습니까?
Rails 3.1에서는
class Form < ActiveRecord::Base
serialize :column, JSON
end
도움이되는 희망
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
도움이 되었기를 바랍니다.
참조 :
정의 serialize
: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L556
레일과 함께 제공되는 기본 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
최신 정보
훨씬 더 적절한 Rails> = 3.1 답변은 아래 mid의 높은 등급 답변을 참조하십시오. 이것은 Rails <3.1에 대한 훌륭한 답변입니다.
아마도 이것은 당신이 찾고있는 것입니다.
Form.find(:first).to_json
최신 정보
1) 'JSON'설치 보석 :
gem install json
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
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
4) 테스트 해보세요!
User.create :name => {"a"=>"b", "c"=>["d", "e"]}
추신:
꽤 건조하지는 않지만 최선을 다했습니다. 누구든지 해결할 수있는 경우 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
건배, 결국 아주 쉽습니다!
기본값을 사용하는 자체 YAML 코더를 작성했습니다. 수업은 다음과 같습니다.
class JSONColumn
def initialize(default={})
@default = default
end
# this might be the database default and we should plan for empty strings or nils
def load(s)
s.present? ? JSON.load(s) : @default.clone
end
# this should only be nil or an object that serializes to JSON (like a hash or array)
def dump(o)
JSON.dump(o || @default)
end
end
이후 load
와 dump
인스턴스 메소드는 그 두 번째 인수로서 전달 될 필요 인스턴스 serialize
모델을 정의. 다음은 그 예입니다.
class Person < ActiveRecord::Base
validate :name, :pets, :presence => true
serialize :pets, JSONColumn.new([])
end
I tried creating a new instance, loading an instance, and dumping an instance in IRB, and it all seemed to work properly. I wrote a blog post about it, too.
The serialize :attr, JSON
using composed_of
method works like this:
composed_of :auth,
:class_name => 'ActiveSupport::JSON',
:mapping => %w(url to_json),
:constructor => Proc.new { |url| ActiveSupport::JSON.decode(url) }
where url is the attribute to be serialized using json and auth is the new method available on your model that saves its value in json format to the url attribute. (not fully tested yet but seems to be working)
A simpler solution is to use composed_of
as described in this blog post by Michael Rykov. I like this solution because it requires the use of fewer callbacks.
Here is the gist of it:
composed_of :settings, :class_name => 'Settings', :mapping => %w(settings to_json),
:constructor => Settings.method(:from_json),
:converter => Settings.method(:from_json)
after_validation do |u|
u.settings = u.settings if u.settings.dirty? # Force to serialize
end
Aleran, have you used this method with Rails 3? I've somewhat got the same issue and I was heading towards serialized when I ran into this post by Michael Rykov, but commenting on his blog is not possible, or at least on that post. To my understanding he is saying that you do not need to define Settings class, however when I try this it keeps telling me that Setting is not defined. So I was just wondering if you have used it and what more should have been described? Thanks.
ReferenceURL : https://stackoverflow.com/questions/2080347/activerecord-serialize-using-json-instead-of-yaml
'IT TIP' 카테고리의 다른 글
프로그래밍 방식으로 특정 연락처에 텍스트 보내기 (whatsapp) (0) | 2020.12.31 |
---|---|
Visual Studio 2013. 컴퓨터의 IIS 웹 사이트에 액세스 할 수있는 권한이 없습니다. (0) | 2020.12.31 |
Github를 떠나, Git 저장소의 출처를 변경하는 방법은 무엇입니까? (0) | 2020.12.31 |
백그라운드에서 .NET 콘솔 애플리케이션을 실행하는 방법 (0) | 2020.12.31 |
UICollectionView-수평 스크롤, 수평 레이아웃? (0) | 2020.12.31 |