Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collecting hashes into OpenStruct creates "table" entry

Tags:

Why this (evaluated in Rails console)

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

adds a "table" record in there?

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

I want just this:

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

Does it mean that Rails' to_json method handles OpenStruct in a different way? When I try it in the irb, it's not there:

require 'ostruct'
[{:a => :b}].collect {|x| OpenStruct.new(x)}.inspect
like image 373
lzap Avatar asked Oct 20 '11 11:10

lzap


2 Answers

Because @table is a instance variable of OpenStruct and Object#as_json returns Hash of instance variables.

In my project, I implemented OpenStruct#as_json to override the behaviour.

require "ostruct"
class OpenStruct
  def as_json(options = nil)
    @table.as_json(options)
  end
end
like image 191
hiroshi Avatar answered Oct 19 '22 02:10

hiroshi


Use marshal_dump, although this somewhat defeats the purpose of converting it to an OpenStruct beforehand:

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

The shorter way would be:

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

Alternatively you could moneky patch OpenStruct#as_json as shown in hiroshi's answer:

require "ostruct"
class OpenStruct
  def as_json(options = nil)
    @table.as_json(options)
  end
end
like image 37
Matt Avatar answered Oct 19 '22 03:10

Matt