Ruby 对象和 JSON 序列化(不带 Rails)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4464050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ruby objects and JSON serialization (without Rails)
提问by BuddyJoe
I'm trying to understand the JSON serialization landscape in Ruby. I'm new to Ruby.
我正在尝试了解 Ruby 中的 JSON 序列化格局。我是 Ruby 的新手。
Is there any good JSON serialization options if you are not working with Rails?
如果您不使用 Rails,是否有任何好的 JSON 序列化选项?
That seems to be where this answer goes (to Rails) How to convert a Ruby object to JSON
这似乎是这个答案的去向(到 Rails) How to convert a Ruby object to JSON
The json gem seems to make it look like you have to write your own to_json method. I haven't been able to get to_json to work with arrays and hashes (documentation says it works with these) Is there a reason the json gem doesn't just reflect over the object and use a default serialization strategy? Isn't this how to_yaml works (guessing here)
json gem 似乎让您看起来必须编写自己的 to_json 方法。我无法让 to_json 使用数组和哈希(文档说它适用于这些)是否有原因 json gem 不只是反映对象并使用默认序列化策略?这不是 to_yaml 的工作原理吗(在这里猜测)
回答by david4dev
For the JSON library to be available, you may have to install libjson-rubyfrom your package manager.
要使 JSON 库可用,您可能必须libjson-ruby从包管理器进行安装。
To use the 'json' library:
要使用“json”库:
require 'json'
To convert an object to JSON (these 3 ways are equivalent):
将对象转换为 JSON(这 3 种方式是等效的):
JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string
To convert JSON text to an object (these 2 ways are equivalent):
将 JSON 文本转换为对象(这两种方式是等效的):
JSON.load string #returns an object
JSON.parse string #returns an object
It will be a bit more difficult for objects from your own classes. For the following class, to_json will produce something like "\"#<A:0xb76e5728>\"".
对于您自己的类中的对象,这会更困难一些。对于下面的类, to_json 将产生类似"\"#<A:0xb76e5728>\"".
class A
def initialize a=[1,2,3], b='hello'
@a = a
@b = b
end
end
This probably isn't desirable. To effectively serialise your object as JSON, you should create your own to_json method. To go with this, a from_json class method would be useful. You could extend your class like so:
这可能是不可取的。为了有效地将您的对象序列化为 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
You could automate this by inheriting from a 'JSONable' class:
您可以通过从“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
Then you can use object.to_jsonto serialise to JSON and object.from_json! stringto copy the saved state that was saved as the JSON string to the object.
然后,您可以使用object.to_json序列object.from_json! string化为 JSON 并将保存为 JSON 字符串的保存状态复制到对象中。
回答by Jimothy
Check out Oj. There are gotchas when it comes to converting any old object to JSON, but Oj can do it.
看看奥杰。将任何旧对象转换为 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
This outputs:
这输出:
{
"^o":"A",
"a":[
1,
2,
3
],
"b":"hello"
}
Note that ^ois used to designate the object's class, and is there to aid deserialization. To omit ^o, use :compatmode:
请注意,^o用于指定对象的类,并在那里帮助反序列化。要省略^o,请使用:compat模式:
puts Oj::dump a, :indent => 2, :mode => :compat
Output:
输出:
{
"a":[
1,
2,
3
],
"b":"hello"
}
回答by Greg Campbell
If rendering performance is critical, you might also want to look at yajl-ruby, which is a binding to the C yajllibrary. The serialization API for that one looks like:
如果渲染性能至关重要,您可能还想查看yajl-ruby,它是 C yajl库的绑定。该序列化 API 如下所示:
require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
回答by Cir0X
Since I searched a lot myself to serialize a Ruby Object to json:
由于我自己搜索了很多将 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}
回答by the Tin Man
What version of Ruby are you using? ruby -vwill tell you.
您使用的是哪个版本的 Ruby?ruby -v会告诉你。
If it's 1.9.2, JSON is included in the standard library.
如果是 1.9.2,则JSON 包含在标准库中。
If you're on 1.8.something then do gem install jsonand it'll install. Then, in your code do:
如果你在 1.8.something 上,那么做gem install json它就会安装。然后,在您的代码中执行以下操作:
require 'rubygems'
require 'json'
Then append to_jsonto an object and you're good to go:
然后附加to_json到一个对象,你很高兴去:
asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"
回答by Reactormonk
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
回答by superluminary
If you're using 1.9.2 or above, you can convert hashes and arrays to nested JSON objects just using to_json.
如果您使用的是 1.9.2 或更高版本,则可以仅使用 to_json 将散列和数组转换为嵌套的 JSON 对象。
{a: [1,2,3], b: 4}.to_json
In Rails, you can call to_json on Active Record objects. You can pass :include and :only parameters to control the output:
在 Rails 中,您可以对 Active Record 对象调用 to_json。您可以传递 :include 和 :only 参数来控制输出:
@user.to_json only: [:name, :email]
You can also call to_json on AR relations, like so:
您还可以在 AR 关系上调用 to_json,如下所示:
User.order("id DESC").limit(10).to_json
You don't need to import anything and it all works exactly as you'd hope.
您不需要导入任何东西,一切都如您所愿。
回答by iainbeeston
回答by Aref Aslani
Jbuilderis a gem built by rails community. But it works well in non-rails environments and have a cool set of features.
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\"}"

