Collecting hashes into OpenStruct creates "table" entry

openstruct to hash
ruby struct
ruby openstruct
rspec openstruct
openstruct dig
ruby strict openstruct
no implicit conversion of openstruct into string
struct to hash ruby

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

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

Collecting hashes into OpenStruct creates "table" entry, Collecting hashes into OpenStruct creates "table" entry. openstruct to hash openstruct dig ruby strict openstruct. Why this (evaluated in Rails console) I really love the way it handles attributes. That's why I've come to appreciate OpenStruct. This handy class allows you to essentially create data structures on the fly. I've also come to really love YAML as a way to represent data structures. I find it more visually appealing and easier to edit than XML. Since Ruby has a built in YAML parser

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

🤽 Collecting hashes in OpenStruct creates a table entry, Use marshal_dump , although this somewhat strikes the goal of converting it to OpenStruct beforehand: [{:a => :b}].collect {|x| OpenStruct.new(x).marshal_dump }​  12 Collecting hashes into OpenStruct creates “table” entry Nov 14 '14 5 How to generate an XOAUTH parameter using OAuth2.0 for use with Gmail IMAP protocol? Dec 28 '11

I get around the problem by subclassing OpenStruct like so:

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

then you can easily convert to JSON like so:

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

Neat huh? So in answer to your question, you'd write this instead:

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

giving you:

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

How to convert an OpenStruct to a Hash, Often the built-in group_by and index_by methods will do the trick. Since Ruby 2.1 you can use to_h to create a Hash by mapping over an array: it solves the problem of Hash key lookup by providing them as methods, for example: require 'ostruct' hash = { a : 1 , b : 2 } mystruct = OpenStruct . new hash mystruct . a # => 1 mystruct . b # => 2 it’s part of the Ruby’s standard library (along with YAML and ERB as well)

With ruby 2.1.2 you can use the following to get JSON without the table root element:

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

All About Ruby OpenStruct, An OpenStruct is a data structure, similar to a Hash, that allows the Create an OpenStruct object, then display it (method :to_s is an alias of  Collecting the hardware ID from existing devices using Microsoft Endpoint Configuration Manager. Microsoft Endpoint Configuration Manager automatically collects the hardware hashes for existing Windows 10 devices. For more information, see Gather information from Configuration Manager for Windows Autopilot. You can extract the hash information from Configuration Manager into a CSV file.

I found the other responses to be a tad confusing having landed here to just figure out how to turn my OpenStruct into a Hash or JSON. To clarify, you can just call marshal_dump on your 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\"}"

I personally would be hesitant to monkey-patch OpenStruct unless you're doing it on a subclass, as it may have unintended consequences.

Practical Object-oriented Design in Ruby: An Agile Primer, initialization arguments while OpenStruct takes a hash for its initialization and There are good reasons to remove the Part class; this simplifies the code and you PartsFactory to use OpenStruct to create an object that plays the Part role. 4 parts_class.new( 5 config.collect {|part_config| 6 create_part(part_config)})  All source code included in the card How to convert an OpenStruct to a Hash is licensed under the license stated below. This includes both code snippets embedded in the card text and code that is included as a file attachment.

Hashie Considered Harmful, They grow attached to hashes and use them in many places they shouldn't; creating and passing hashes when a proper Plain Old Ruby Object  Okay so we get no errors, but it “feels” like an object. Open struct can be a convenient way to pass around data, but it has similar limitations to a Hash. Even better, OpenStruct has hash-like operators, we can use it almost like a hash. The key word here is “almost”.

Ruby Hash to Object with OpenStruct and JSON · zaiste.net, In Ruby you can convert a hash into an object using OpenStruct from the Ruby Standard Library. There is a substantial overhead when creating OpenStruct. Creating Hashes. As with arrays, there is a variety of ways to create hashes. You can create an empty hash with the new class method − months = Hash.new You can also use new to create a hash with a default value, which is otherwise just nil − months = Hash.new( "month" ) or months = Hash.new "month"

OpenStruct to valid JSON through Hash · Issue #1 · polomasta/rails , That OpenStruct format being pushed to our richtext renderer to be the /​collecting-hashes-into-openstruct-creates-table-entry/13777745  Hash::Wrap creates objects from hashes, providing accessors for hash elements. The objects are hashes, and may be modified using the standard Perl hash operations and the object's accessors will behave accordingly.

Comments
  • Yeah, the reason why I am doing that is I need to change the original hash structure (rename some fields, drop some others).
  • Works like a charm. If there is any better way of doing that, let me know: gist.github.com/1300921
  • Any downside to to_h.as_json(options) rather than referencing @table? It seems safer to use the public interface, even if I'm subclassing Ostruct.
  • I have been looking to over-ride the OpenStruct's inspect method all day now, and this is the only thing that has worked for me. Thanks.
  • Exactly what I need! You saved my day! Thx
  • Note I had to do super['table'] to get this to work.