J'ai un modèle qui utilise une colonne sérialisée:
class Form < ActiveRecord::Base
serialize :options, Hash
end
Existe-t-il un moyen de faire en sorte que cette sérialisation utilise JSON au lieu de YAML?
J'ai un modèle qui utilise une colonne sérialisée:
class Form < ActiveRecord::Base
serialize :options, Hash
end
Existe-t-il un moyen de faire en sorte que cette sérialisation utilise JSON au lieu de YAML?
Dans les Rails 3.1 vous pouvez utiliser des codeurs avec 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
Espérons que cette aide.
Références:
Définition de l' serialize
:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L556
La valeur par défaut YAML codeur qui est livré avec des rails: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/coders/yaml_column.rb
Et c'est là que l'appel à l' load
qui se passe:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/read.rb#L132
Mise à jour
Voir le milieu de la haute note de réponse ci-dessous pour un beaucoup plus approprié Rails >= 3.1 réponse. C'est une excellente réponse pour les Rails < 3.1.
C'est probablement ce que vous cherchez.
Form.find(:first).to_json
Mise à jour
1) Installer 'json' gem:
gem install json
2) Créer JsonWrapper classe
# 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) Ajouter le modèle rappels:
#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) Tester!
User.create :name => {"a"=>"b", "c"=>["d", "e"]}
Ce n'est pas tout à fait SEC, mais j'ai fait de mon mieux. Si quelqu'un peut résoudre after_find
en User
modèle, ça va être génial.
Mes exigences n'ayant pas nécessité beaucoup de réutilisation de code à ce stade, mon code distillé est une variante de la réponse ci-dessus:
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
Salut, assez facile à la fin!
La méthode serialize :attr, JSON
utilisant composed_of
fonctionne comme suit:
composed_of :auth,
:class_name => 'ActiveSupport::JSON',
:mapping => %w(url to_json),
:constructor => Proc.new { |url| ActiveSupport::JSON.decode(url) }
où url est l'attribut à sérialiser à l'aide de json et auth est la nouvelle méthode disponible sur votre modèle qui enregistre sa valeur au format json dans l'attribut url. (pas encore complètement testé mais semble fonctionner)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.