72

我正在尝试了解 Ruby 中的 JSON 序列化环境。我是红宝石的新手。

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

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

json gem 似乎让您看起来必须编写自己的 to_json 方法。我无法让 to_json 使用数组和哈希(文档说它适用于这些) json gem 不只是反映对象并使用默认序列化策略是否有原因?这不是 to_yaml 的工作方式吗(在这里猜测)

4

11 回答 11

113

要使 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序列object.from_json! string化为 JSON 并将保存为 JSON 字符串的已保存状态复制到对象。

于 2010-12-16T19:42:51.710 回答
11

查看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"
}
于 2013-06-19T03:10:58.493 回答
8

如果渲染性能很关键,您可能还想查看yajl-ruby,它是与 C yajl库的绑定。该序列化 API 如下所示:

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
于 2010-12-16T19:30:54.037 回答
7

您使用的是哪个版本的 Ruby?ruby -v会告诉你。

如果是 1.9.2,则 JSON 包含在标准库中。

如果你在 1.8.something 然后做gem install json,它会安装。然后,在您的代码中执行以下操作:

require 'rubygems'
require 'json'

然后附加to_json到一个对象,你很高兴:

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"
于 2010-12-16T23:58:07.723 回答
7

因为我自己搜索了很多以将 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}
于 2016-08-02T10:49:17.987 回答
4
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
于 2010-12-16T18:22:50.480 回答
1

要让构建类(如数组和哈希)支持as_jsonand to_json,您需要require 'json/add/core'(有关详细信息,请参阅自述文件

于 2015-04-05T13:47:26.783 回答
1

如果您使用的是 1.9.2 或更高版本,则可以仅使用 to_json 将哈希和数组转换为嵌套的 JSON 对象。

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

在 Rails 中,您可以在 Active Record 对象上调用 to_json。您可以传递 :include 和 :only 参数来控制输出:

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

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

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

你不需要导入任何东西,一切都如你所愿。

于 2013-05-10T09:37:19.953 回答
1

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\"}"
于 2016-09-25T09:49:49.417 回答
0

实际上,有一个叫做 Jsonable 的 gem,https://github.com/treeder/jsonable。它很甜。

于 2014-11-13T11:24:30.420 回答
0

我曾经virtus。真正强大的工具,允许根据您指定的类创建动态的 Ruby 结构结构。简单的 DSL,可以从 ruby​​ 哈希创建对象,有严格模式。检查一下

于 2016-01-15T23:44:43.437 回答