Сбор хэшей в OpenStruct создает запись "table"
Почему это (оценивается в консоли 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
Ответы
Ответ 1
Используйте marshal_dump
, хотя это несколько поражает цель его предварительного преобразования в OpenStruct:
[{:a => :b}].collect {|x| OpenStruct.new(x).marshal_dump }.to_json
=> "[{\"a\":\"b\"}]"
Более короткий путь:
[{:a => :b}].to_json
"[{\"a\":\"b\"}]"
В качестве альтернативы вы могли бы moneky patch OpenStruct#as_json
, как показано в hiroshi ответе:
require "ostruct"
class OpenStruct
def as_json(options = nil)
@table.as_json(options)
end
end
Ответ 2
Потому что @table - это переменная экземпляра OpenStruct и Объект # as_json возвращает Hash переменных экземпляра.
В моем проекте я реализовал OpenStruct # as_json, чтобы переопределить поведение.
require "ostruct"
class OpenStruct
def as_json(options = nil)
@table.as_json(options)
end
end
Ответ 3
Я обойду проблему, подклассифицируя 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\"}]"
Ответ 4
С ruby 2.1.2 вы можете использовать следующее, чтобы получить JSON без корневого элемента таблицы:
[{:a => :b}].collect {|x| OpenStruct.new(x).to_h}.to_json
=> "[{\"a\":\"b\"}]"
Ответ 5
Я нашел, что другие ответы были немного запутанными, приземлившись здесь, чтобы просто выяснить, как превратить 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\"}"
Я лично был бы неспособен к monkey-patch OpenStruct
, если вы не делаете это в подклассе, так как это может иметь непреднамеренные последствия.
Ответ 6
openstruct_array.map(&:to_h).as_json