Ruby 对象和 JSON 序列化(没有 Rails)

我正试图理解 Ruby 中的 JSON 序列化环境。

如果不使用 Rails,是否有好的 JSON 序列化选项?

这似乎就是这个问题的答案(Rails) 如何将 Ruby 对象转换为 JSON

Json gem 似乎使您必须编写自己的 to _ json 方法。 我还不能使用 _ json 来处理数组和散列(文档说它可以处理这些) 为什么 json gem 不仅仅反映对象并使用默认的序列化策略呢?这不是如何 _ yaml 工作(在这里猜测)

111017 次浏览
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"

如果呈现性能很关键,那么您可能还需要查看 Yajl-ruby,它是到 C 干杯库的绑定。它的序列化 API 看起来像:

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

为了使 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 文本转换为对象(这两种方法是等价的) :

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 字符串复制到对象。

你使用的是什么版本的 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"}"

如果使用的是1.9.2或更高版本,可以使用 to _ JSON 将散列和数组转换为嵌套的 JSON 对象。

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

在 Rails 中,可以对 ActiveRecord 对象调用 to _ json。可以传递: include 和: only 参数来控制输出:

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

您还可以在 AR 关系上调用 _ json,如下所示:

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

您不需要导入任何东西,所有工作都完全按照您希望的那样进行。

看看 橙汁。当涉及到将任何旧对象转换为 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"
}

事实上,有一个宝石叫做 Jsonable,https://github.com/treeder/jsonable。它是相当甜蜜的。

要使类(如 Array 和 Hash)中的构建支持 as_jsonto_json,您需要 require 'json/add/core'(参见 自述了解详细信息)

我以前用 virtus。真正强大的工具,允许创建一个动态的 Ruby 结构结构基于您指定的类。简单的 DSL,可以从 Ruby 散列中创建对象,有严格的模式。看看

因为我自己搜索了很多来序列化 Ruby 对象到 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}

JBuilder 是 Rails 社区构建的 gem。但是它在非 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\"}"