ActiveRecord sérialiser en utilisant JSON au lieu de YAML
J'ai un modèle qui utilise un sérialisé colonne:
class Form < ActiveRecord::Base
serialize :options, Hash
end
Est-il un moyen de rendre cette utilisation de la sérialisation JSON au lieu de YAML?
- J'espérais qu'il y aurait une certaine "magie" ou de plugin, mais la solution est très simple et fonctionne très bien.
- toby , vous pouvez changer la accepté de répondre à celui-ci? stackoverflow.com/a/6971678/190135 voir meta.stackexchange.com/questions/120568/...
Vous devez vous connecter pour publier un commentaire.
Dans les Rails 3.1, vous pouvez simplement
Espère que ça aide
[:dump, :load].all {|s| ::JSON.respond_to? s}
, tout comme la valeur par défautYAMLColumn
n'. Dans un contrôleur,JSON == ::JSON
etJSON != ::ActiveSupport::JSON
..dump(obj)
et.load(obj)
il sera utilisé en tant que codeur/sérialiseur. Sinon, la valeur par défaut YAMLColumn classe est utilisé en tant que codeur/sérialiseur. Le vidage de charge et de méthodes peuvent également être directement mis en œuvre dans une Classe de Modèle, vous n'avez pas pour pour utiliser une salle de classe distincte à faire le codage.NoMethodError: undefined method `read' for nil:NilClass
Dans les Rails 3.1 vous pouvez utiliser des codeurs avec
serialize
.Espère que cette aide.
Références:
Définition de
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 à la
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.
Mise à jour
1) Installer 'json' gem:
2) Créer JsonWrapper classe
3) Ajouter le modèle rappels:
4) Tester!
PS:
Ce n'est pas tout à fait SEC, mais j'ai fait de mon mieux. Si quelqu'un peut résoudre
after_find
dansUser
modèle, ça va être génial.Mes exigences n'ont pas besoin de beaucoup de code ré-utiliser à ce stade, donc, mon distillée code est une variation de la réponse ci-dessus:
Acclamations, assez facile en fin de compte!
input = 'foo'; serialized = input.to_json; JSON.parse(serialized)
#=> JSON::ParserError: 757: unexpected token à " "toto"' de /Utilisateurs/nom_utilisateur/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/json-1.8.3/lib/json/commun.rb:155:dans `analyser' makandracards.com/makandra/... Une bonne solution pour cela est d'utiliser Ruby Maréchal de la bibliothèque. C'est plus rapide et plus fiable que le JSON ou YAML.J'ai écrit mes propres YAML codeur, qui prend une valeur par défaut. Ici, c'est la classe:
Depuis
load
etdump
sont les méthodes d'instance, il requiert une instance d'être passé en second argument de laserialize
dans la définition du modèle. Voici un exemple:J'ai essayé de créer une nouvelle instance, le chargement d'une instance, et le dumping une instance de la CISR, et tout semblait fonctionner correctement. J'ai écrit un post de blog à ce sujet, aussi.
lib/json_column.rb
et ajouterrequire 'json_column'
àconfig/environment.rb
.La
serialize :attr, JSON
à l'aide decomposed_of
méthode fonctionne comme ceci:où url est l'attribut d'être sérialisée en utilisant json
et auth est la nouvelle méthode de disponible sur votre modèle qui sauve sa valeur au format json à l'url de l'attribut. (pas entièrement encore testé, mais semble être le travail)
Une solution plus simple est d'utiliser
composed_of
comme décrit dans cet article de blog par Michael Rykov. J'aime bien cette solution, car elle nécessite l'utilisation de moins de rappels.Voici l'essentiel:
Aleran, avez-vous utilisé cette méthode avec Rails 3? J'ai un peu eu le même problème et j'ai été dirigeant vers sérialisé quand je suis tombé sur ce post par Michael Rykov, mais faire un commentaire sur son blog n'est pas possible, ou au moins sur ce poste. De ma compréhension, il est en train de dire que vous n'avez pas besoin de définir les Paramètres de la classe, cependant lorsque j'essaie de cela, il continue à me dire que le Paramètre n'est pas défini. Donc je me demandais si vous l'avez utilisé, et ce qui devrait avoir été décrit? Merci.