web-dev-qa-db-fra.com

Ruby et sérialisation JSON (sans Rails)

J'essaie de comprendre le paysage de la sérialisation JSON dans Ruby. Je suis nouveau à Ruby.

Existe-t-il de bonnes options de sérialisation JSON si vous ne travaillez pas avec Rails?

Cela semble être où cette réponse va (à Rails) Comment convertir un objet Ruby en JSON

La gemme json semble donner l’impression que vous devez écrire votre propre méthode to_json. To_json n'a pas pu utiliser les tableaux et les hachages (la documentation indique que cela fonctionne) Existe-t-il une raison pour laquelle la gemme Json ne se contente pas de refléter sur l'objet et utilise une stratégie de sérialisation par défaut? N'est-ce pas comme cela que to_yaml fonctionne (deviner ici)

68
BuddyJoe

Pour que la bibliothèque JSON soit disponible, vous devrez peut-être installer libjson-Ruby de votre gestionnaire de paquets.

Pour utiliser la bibliothèque 'json':

require 'json'

Pour convertir un objet en JSON (ces 3 manières sont équivalentes):

JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string

Pour convertir du texte JSON en objet (ces deux méthodes sont équivalentes):

JSON.load string #returns an object
JSON.parse string #returns an object

Ce sera un peu plus difficile pour les objets de vos propres classes. Pour la classe suivante, to_json produira quelque chose comme: "\"#<A:0xb76e5728>\"".

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

Ce n'est probablement pas souhaitable. Pour sérialiser efficacement votre objet en tant que JSON, vous devez créer votre propre méthode to_json. Pour aller avec cela, une méthode de classe from_json serait utile. Vous pouvez prolonger votre classe comme suit:

class A
    def to_json
        {'a' => @a, 'b' => @b}.to_json
    end
    def self.from_json string
        data = JSON.load string
        self.new data['a'], data['b']
    end
end

Vous pouvez automatiser cela en héritant d'une classe 'JSONable':

class JSONable
    def to_json
        hash = {}
        self.instance_variables.each do |var|
            hash[var] = self.instance_variable_get var
        end
        hash.to_json
    end
    def from_json! string
        JSON.load(string).each do |var, val|
            self.instance_variable_set var, val
        end
    end
end

Ensuite, vous pouvez utiliser object.to_json pour sérialiser en JSON et object.from_json! string pour copier l'état enregistré enregistré en tant que chaîne JSON dans l'objet.

105
david4dev

Départ Oj . Il est difficile de convertir n'importe quel objet ancien en JSON, mais Oj peut le faire.

require 'oj'

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

a = A.new
puts Oj::dump a, :indent => 2

Cela génère:

{
  "^o":"A",
  "a":[
    1,
    2,
    3
  ],
 "b":"hello"
}

Notez que ^o est utilisé pour désigner la classe de l'objet et sert à faciliter la désérialisation. Omettre ^o, utilisation :compat mode:

puts Oj::dump a, :indent => 2, :mode => :compat

Sortie:

{
  "a":[
    1,
    2,
    3
  ],
  "b":"hello"
}
11
Jimothy

Si les performances de rendu sont essentielles, vous pouvez également consulter yajl-Ruby , qui est une liaison à la bibliothèque C yajl . L'API de sérialisation pour celui-ci ressemble à:

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
8
Greg Campbell

Quelle version de Ruby utilisez-vous? Ruby -v vous le dira.

Si c'est 1.9.2, JSON est inclus dans la bibliothèque standard .

Si vous êtes sur 1.8.Quelque chose, alors faites gem install json et ça va installer. Ensuite, dans votre code, faites:

require 'rubygems'
require 'json'

Puis ajoutez to_json à un objet et vous êtes prêt à partir:

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"
7
the Tin Man

Depuis que j'ai moi-même beaucoup cherché à sérialiser un Ruby Object to json:

require 'json'

class User
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def as_json(options={})
    {
      name: @name,
      age: @age
    }
  end

  def to_json(*options)
    as_json(*options).to_json(*options)
  end
end

user = User.new("Foo Bar", 42)
puts user.to_json #=> {"name":"Foo Bar","age":42}
6
Cir0X
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
4
Reactormonk

Pour que les classes de construction (comme Array et Hash) supportent as_json et to_json, tu dois require 'json/add/core' _ (voir le readme pour plus de détails)

1
iainbeeston

Si vous utilisez 1.9.2 ou une version ultérieure, vous pouvez convertir des hachages et des tableaux en objets JSON imbriqués en utilisant simplement to_json.

{a: [1,2,3], b: 4}.to_json

Dans Rails, vous pouvez appeler to_json sur les objets Active Record. Vous pouvez passer: include et: uniquement des paramètres pour contrôler la sortie:

@user.to_json only: [:name, :email]

Vous pouvez également appeler to_json sur les relations AR, comme suit:

User.order("id DESC").limit(10).to_json

Vous n'avez pas besoin d'importer quoi que ce soit et tout fonctionne exactement comme vous le souhaiteriez.

1
superluminary

Jbuilder est un joyau construit par la communauté Rails. Mais il fonctionne bien dans les environnements autres que Rails et possède un ensemble de fonctionnalités intéressantes.

# suppose we have a sample object as below
sampleObj.name #=> foo
sampleObj.last_name #=> bar

# using jbuilder we can convert it to json:
Jbuilder.encode do |json|
  json.name sampleObj.name
  json.last_name sampleObj.last_name
end #=> "{:\"name\" => \"foo\", :\"last_name\" => \"bar\"}"
1
Aref Aslani

J'avais l'habitude de virtus. Outil vraiment puissant, permet de créer une structure de structure dynamique Ruby basée sur vos classes spécifiées. Easy DSL, possible de créer des objets à partir de Ruby hashes, il est strict Mode. Vérifiez it out.

0
ka8725

En fait, il existe une gemme appelée Jsonable, https://github.com/treeder/jsonable . C'est assez gentil.

0
dentarg