Ruby-объекты и JSON-сериализация (без Rails) - PullRequest
67 голосов
/ 16 декабря 2010

Я пытаюсь понять ландшафт сериализации JSON в Ruby. Я новичок в Ruby.

Есть ли хорошие варианты сериализации JSON, если вы не работаете с Rails?

Похоже, что этот ответ идет (к Rails) Как преобразовать объект Ruby в JSON

Похоже, что с помощью json gem вы должны написать собственный метод to_json. Я не смог заставить to_json работать с массивами и хешами (в документации сказано, что это работает с ними) Есть ли причина, по которой гем json не просто отражает объект и использует стратегию сериализации по умолчанию? Разве не так to_yaml работает (догадываясь здесь)

Ответы [ 11 ]

104 голосов
/ 16 декабря 2010

Чтобы библиотека JSON была доступна, вам, возможно, придется установить libjson-ruby из диспетчера пакетов.

Чтобы использовать библиотеку 'json':

require 'json'

Чтобы преобразовать объект в JSON (эти 3 способа эквивалентны):

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

Чтобы преобразовать текст JSON в объект (эти 2 способа эквивалентны):

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

Это будет немного сложнее для объектов из ваших собственных классов. Для следующего класса to_json выдаст что-то вроде "\"#<A:0xb76e5728>\"".

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

Это, вероятно, не желательно. Чтобы эффективно сериализовать ваш объект как JSON, вы должны создать свой собственный метод to_json. Для этого был бы полезен метод класса from_json. Вы можете расширить свой класс так:

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

Вы можете автоматизировать это, унаследовав класс 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

Затем вы можете использовать object.to_json для сериализации в JSON и object.from_json! string для копирования сохраненного состояния, которое было сохранено как строка JSON, в объект.

11 голосов
/ 19 июня 2013

Выезд Oj . Когда дело доходит до конвертации любого старого объекта в JSON, есть ошибки, но Oj может это сделать.

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

Это выводит:

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

Обратите внимание, что ^o используется для обозначения класса объекта и используется для десериализации. Чтобы пропустить ^o, используйте режим :compat:

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

Выход:

{
  "a":[
    1,
    2,
    3
  ],
  "b":"hello"
}
8 голосов
/ 16 декабря 2010

Если производительность рендеринга критична, вы также можете посмотреть на yajl-ruby , который является привязкой к библиотеке C yajl . API сериализации для этого выглядит так:

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
7 голосов
/ 17 декабря 2010

Какую версию Ruby вы используете?ruby -v скажет вам.

Если это 1.9.2, JSON включен в стандартную библиотеку .

Если вы используете 1.8.что-то, то сделайте gem install json, и он установится.Затем в вашем коде выполните:

require 'rubygems'
require 'json'

Затем добавьте to_json к объекту, и все готово:

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"
5 голосов
/ 02 августа 2016

Поскольку я много искал, чтобы сериализовать Ruby Object в 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}
4 голосов
/ 16 декабря 2010
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
1 голос
/ 25 сентября 2016

Jbuilder - это драгоценный камень, созданный сообществом rails.Но он хорошо работает в среде без рельсов и обладает отличным набором функций.

# 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 голос
/ 05 апреля 2015

Чтобы классы сборки (такие как Array и Hash) поддерживали as_json и to_json, вам необходимо require 'json/add/core' (подробности см. В readme )

1 голос
/ 10 мая 2013

Если вы используете 1.9.2 или выше, вы можете конвертировать хэши и массивы во вложенные объекты JSON, просто используя to_json

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

В Rails вы можете вызывать to_json для объектов Active Record. Вы можете передать: include и: только параметры для управления выводом:

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

Вы также можете вызвать to_json для отношений AR, например:

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

Вам не нужно ничего импортировать, и все работает точно так, как вы надеетесь.

0 голосов
/ 16 января 2016

Я привык virtus. Действительно мощный инструмент, позволяющий создать динамическую структуру структуры Ruby на основе заданных вами классов. Легкий DSL, возможно создание объектов из рубиновых хэшей, есть строгий режим. Проверьте это из.

...