Deep Convert OpenStruct for JSON

I have OpenStruct , which includes many other OpenStructs . What is the best way to deeply convert them all to JSON?

Perfectly:

 x = OpenStruct.new xy = OpenStruct.new xyz = OpenStruct.new z = 'hello' x.to_json // {y: z: 'hello'} 

reality

 { <OpenStruct= ....> } 
+6
source share
3 answers

There are no standard methods for this task, because the built-in #to_hash returns a Hash representation, but does not do deep value conversions.

If the value is OpenStruct , it is returned as such and is not converted to Hash .

However, this is not so difficult to solve. You can create a method that intersects each key / value in an OpenStruct instance (for example, using each_pair ), recursively descends into a nested OpenStruct if the value is equal to OpenStruct and returns a Hash only the basic Ruby types.

Such a Hash can be easily serialized using either .to_json or JSON.dump(hash) .

This is a very quick example.

 def openstruct_to_hash(object, hash = {}) object.each_pair do |key, value| hash[key] = value.is_a?(OpenStruct) ? openstruct_to_hash(value) : value end hash end openstruct_to_hash(OpenStruct.new(foo: 1, bar: OpenStruct.new(baz: 2))) # => {:foo=>1, :bar=>{:baz=>2}} 
+9
source

Fixed solution above for processing arrays

 def open_struct_to_hash(object, hash = {}) object.each_pair do |key, value| hash[key] = case value when OpenStruct then open_struct_to_hash(value) when Array then value.map { |v| open_struct_to_hash(v) } else value end end hash end 
+8
source

The same function that can take arrays as input

  def openstruct_to_hash(object, hash = {}) case object when OpenStruct then object.each_pair do |key, value| hash[key] = openstruct_to_hash(value) end hash when Array then object.map { |v| openstruct_to_hash(v) } else object end end 
0
source

Source: https://habr.com/ru/post/1233569/


All Articles