Объекты Ruby и сериализация JSON (без Rails)
Я пытаюсь понять ландшафт сериализации JSON в Ruby. Я новичок в Ruby.
Есть ли хорошие варианты сериализации JSON, если вы не работаете с Rails?
Кажется, что этот ответ идет (к Rails)
Как преобразовать объект Ruby в JSON
Кажется, что json gem выглядит так, будто вы должны написать свой собственный метод to_json.
Мне не удалось заставить to_json работать с массивами и хешами (документация говорит, что он работает с ними)
Есть ли причина, по которой json gem не просто отражает объект и использует стратегию сериализации по умолчанию? Разве это не так, как to_yaml работает (угадывая здесь)
Ответы
Ответ 1
Чтобы библиотека JSON была доступна, вам, возможно, придется установить libjson-ruby
из диспетчера пакетов.
Чтобы использовать библиотеку json:
require 'json'
Чтобы преобразовать объект в JSON (эти три способа эквивалентны):
JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string
Чтобы преобразовать текст JSON в объект (эти два способа эквивалентны):
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 для объекта.
Ответ 2
Если производительность рендеринга имеет решающее значение, вы также можете посмотреть yajl-ruby, который является связыванием с C yajl. API-интерфейс сериализации для этого выглядит следующим образом:
require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
Ответ 3
Проверьте 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"
}
Ответ 4
Какую версию 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
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
Ответ 6
Поскольку я много раз искал, чтобы сериализовать 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}
Ответ 7
Если вы используете 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
Вам не нужно ничего импортировать, и все работает так, как вы надеетесь.
Ответ 8
Чтобы получить сборку в классах (например, Array и Hash) для поддержки as_json
и to_json
, вам нужно require 'json/add/core'
(см. readme для деталей)
Ответ 9
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\"}"
Ответ 10
На самом деле есть драгоценный камень под названием Jsonable, https://github.com/treeder/jsonable. Это очень мило.
Ответ 11
Я использовал virtus
. Действительно мощный инструмент, позволяет создавать динамическую структуру структуры Ruby на основе ваших указанных классов. Легкая DSL, возможность создания объектов из рубиновых хэшей, существует строгий режим. Проверьте it вне.