将哈希收集到OpenStruct中会创建“表”条目

时间:2011-10-20 11:10:56

标签: ruby-on-rails ruby

为什么这个(在Rails控制台中评估)

[{:a => :b}].collect {|x| OpenStruct.new(x)}.to_json

在那里添加“表”记录?

"[{\"table\":{\"a\":\"b\"}}]

我想要这样:

"[{\"a\":\"b\"}]

这是否意味着Rails的to_json方法以不同的方式处理OpenStruct?当我在irb中尝试它时,它不在那里:

require 'ostruct'
[{:a => :b}].collect {|x| OpenStruct.new(x)}.inspect

7 个答案:

答案 0 :(得分:25)

因为@table is a instance variable of OpenStructObject#as_json returns Hash of instance variables

在我的项目中,我实现了OpenStruct#as_json来覆盖行为。

require "ostruct"
class OpenStruct
  def as_json(options = nil)
    @table.as_json(options)
  end
end

答案 1 :(得分:15)

使用marshal_dump,虽然这有点违背了事先将其转换为OpenStruct的目的:

[{:a => :b}].collect {|x| OpenStruct.new(x).marshal_dump }.to_json
=> "[{\"a\":\"b\"}]"

更短的方式是:

[{:a => :b}].to_json
"[{\"a\":\"b\"}]"

另外,如hiroshi的答案所示,你可以使用moneky patch OpenStruct#as_json

require "ostruct"
class OpenStruct
  def as_json(options = nil)
    @table.as_json(options)
  end
end

答案 2 :(得分:9)

我通过像这样继承OpenStruct来解决这个问题:

class DataStruct < OpenStruct
  def as_json(*args)
    super.as_json['table']
  end
end

然后您可以轻松转换为JSON,如下所示:

o = DataStruct.new(a:1, b:DataStruct.new(c:3))
o.to_json
# => "{\"a\":1,\"b\":{\"c\":3}}"

整洁吧?所以在回答你的问题时,你会写下这个:

[{:a => :b}].collect {|x| DataStruct.new(x)}.to_json

给你:

=> "[{\"a\":\"b\"}]"

答案 3 :(得分:4)

使用ruby 2.1.2,您可以使用以下内容来获取没有表根元素的JSON:

[{:a => :b}].collect {|x| OpenStruct.new(x).to_h}.to_json
 => "[{\"a\":\"b\"}]"

答案 4 :(得分:2)

我发现其他回复有点混乱,只是想知道如何将我的OpenStruct转换为Hash或JSON。为了澄清,您只需在marshal_dump上致电OpenStruct

$ OpenStruct.new(hello: :world).to_json
=> "{\"table\":{\"hello\":\"world\"}}"

$ OpenStruct.new(hello: :world).marshal_dump
=> {:hello=>:world}

$ OpenStruct.new(hello: :world).marshal_dump.to_json
=> "{\"hello\":\"world\"}"

我个人会犹豫猴子补丁OpenStruct,除非你在子类上做,因为它可能会产生意想不到的后果。

答案 5 :(得分:0)

openstruct_array.map(&:to_h).as_json

答案 6 :(得分:0)

这里的问题是,它在内部执行一个 as_json,它使用表键创建一个哈希(因为 as_json 也序列化了对象的所有实例变量,而 @table 是 OpenStruct 的实例变量) 然后它在字符串化它的那个上做一个 to_json

所以,最简单的方法是首先使用 to_h(它不序列化实例变量),然后使用 to_json。所以:

OpenStruct.new(x).to_h.json 或在您的情况下 open_struct_array.map(&:to_h).to_json

相关问题