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 답변을 보려면 아래 중간 등급의 답변을 참조하십시오.이는 Rails < 3.1에 대한 훌륭한 답변입니다.
아마 이게 네가 찾고 있는 거겠지.
Form.find(:first).to_json
갱신하다
1) 'json' Gem 설치:
gem install json
2) Json Wrapper 클래스 만들기
# 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"]}
PS:
건조하진 않지만 최선을 다했어요.고칠 수 있는 사람이 있다면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
건배, 결국엔 꽤 쉬웠죠!
그serialize :attr, JSON
사용.composed_of
방법은 다음과 같습니다.
composed_of :auth,
:class_name => 'ActiveSupport::JSON',
:mapping => %w(url to_json),
:constructor => Proc.new { |url| ActiveSupport::JSON.decode(url) }
여기서 url은 json을 사용하여 serialize되는 Atribute이며 auth는 url Atribute에 json 형식으로 값을 저장하는 모델에서 사용할 수 있는 새로운 메서드입니다.(아직 완전히 테스트되지 않았지만 작동하는 것 같습니다.)
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
새 인스턴스를 만들고, 인스턴스를 로드하고, IRB에 인스턴스를 덤프하려고 했는데 모두 정상적으로 동작하는 것 같았습니다.저도 블로그에 글을 썼어요.
보다 간단한 해결책은composed_of
마이클 라이코프의 블로그 투고에서 설명한 바와 같이요.이 솔루션은 콜백 사용이 적기 때문에 마음에 듭니다.
요점은 다음과 같습니다.
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
알레란, 레일 3에서 이 방법을 사용해 본 적이 있나요?저도 같은 문제가 있어서 연재를 하려고 했는데 마이클 라이코프의 글을 우연히 보게 되었습니다만, 그의 블로그에 코멘트는 할 수 없습니다.제가 알기로는 Settings 클래스를 정의할 필요가 없다고 합니다만, 이것을 시도하면 Setting은 정의되어 있지 않다고 계속 표시됩니다.그래서 나는 단지 당신이 그것을 사용했는지 그리고 무엇을 더 설명해야 했는지 궁금했다.감사해요.
언급URL : https://stackoverflow.com/questions/2080347/activerecord-serialize-using-json-instead-of-yaml
'programing' 카테고리의 다른 글
PHP의 JSON POST에서 HTTP 요청 본문을 읽는 동안 문제가 발생했습니다. (0) | 2023.02.23 |
---|---|
react-testing-library 사용 시 "myText" 오류가 있는 요소를 찾을 수 없습니다. (0) | 2023.02.23 |
스프링 부츠 및 앵귤러 J가 있는 CORS가 작동하지 않음 (0) | 2023.02.23 |
"로케이터에 대해 둘 이상의 요소를 찾았습니다" 경고 (0) | 2023.02.23 |
명령어 정의에서 객체를 반환하는 것과 함수를 반환하는 것의 차이점 (0) | 2023.02.23 |