How to create a JSON structure in Ruby manually?

18,886

Solution 1

If you want to create JSON you use the JSON standard-library which comes with Ruby:

require 'json'

foo = {
  'a' => 1,
  'b' => [2,3]
}

puts JSON[foo]
# >> {"a":1,"b":[2,3]}

If you're trying to figure out how to create a particular JSON output based on a Ruby hash or array, it's easily done by reversing the process and starting with a sample of the desired JSON, and letting the parser turn it into the base object:

JSON['{"a":1,"b":[2,3]}'] # => {"a"=>1, "b"=>[2, 3]}

To modify an existing JSON string, parse it into a Ruby object, modify that, then output it again:

bar = JSON['{"a":1,"b":[2,3]}']
bar['c'] = 'more data'

puts JSON[bar]

# >> {"a":1,"b":[2,3],"c":"more data"}

It's important to note that your example

params_map = '{ "field1" => {"field1a"=>"some text"},
                "field2" => {
                  "field2a"  => "a",
                  "field2b"  => "b",
                  "field2c"  => "c",
                  "field2d"  => {"field2d_a" => "2d_a"},
                  "field2e"  => "e",
                  "items"    => [
                    { "items_a" => "1", 
                      "items_b" => "2",
                      "items_c" => "3",
                      "items_d" => "4"
                    },
                    { "items_e" => "5", 
                      "items_f" => "6",
                      "items_g" => "7",
                      "items_h" => "8"
                    }]
                },
                "field3" => "field3 text",
                "field4" => "field4 text"}'

is not JSON. It's a string:

foo = '{"a" => 1}'
foo.class  # => String

Remove the wrapping ' and you have a hash of hashes:

foo = {"a" => 1, "b" => {"c" => 3}}
foo.class  # => Hash

Solution 2

Merge or Update Ruby Hashes

Generally, the right thing to do is to use Hash#merge! or Hash#update to modify the contents of a Ruby hash, and then convert the results to JSON. For example:

require 'json'

# Add items to your Hash object.    
params_map = {'field1' => 'foo', 'field2' => 'bar', 'field3' => 'baz'}
params_map.merge! 'field4' => 'quux'
#=> {"field1"=>"foo", "field2"=>"bar", "field3"=>"baz", "field4"=>"quux"}

# Convert Hash object to JSON string.
params_map.to_json
#=> "{\"field1\":\"foo\",\"field2\":\"bar\",\"field3\":\"baz\",\"field4\":\"quux\"}"

Solution 3

You can try with OpenStruct http://ruby-doc.org/stdlib-2.0.0/libdoc/ostruct/rdoc/OpenStruct.html , you can iterate your database and add new key pairs on the fly.

Simple example:

struct = OpenStruct.new
struct.foo = 'bar'
struct.baz = 'biz'
json_struct = struct.to_json

--> {"foo": "bar", "baz": "biz"}
Share:
18,886

Related videos on Youtube

user984621
Author by

user984621

Updated on September 15, 2022

Comments

  • user984621
    user984621 over 1 year

    I spent last couple of hours of trying to manually (without Active Record to create a structure like this, taken from an API's documentation:

    params_map = '{ "field1" => {"field1a"=>"some text"},
                    "field2" => {
                      "field2a"  => "a",
                      "field2b"  => "b",
                      "field2c"  => "c",
                      "field2d"  => {"field2d_a" => "2d_a"},
                      "field2e"  => "e",
                      "items"    => [
                        { "items_a" => "1", 
                          "items_b" => "2",
                          "items_c" => "3",
                          "items_d" => "4"
                        },
                        { "items_e" => "5", 
                          "items_f" => "6",
                          "items_g" => "7",
                          "items_h" => "8"
                        }]
                    },
                    "field3" => "field3 text",
                    "field4" => "field4 text"}'
    params_map_eval = eval(params_map)
    

    How can I create this in Ruby? I tried to create it as a Hash using Hash.new, also as a JSON, but I failed at adding/appending another fields to the big JSON.

    The items will be a loop and I'll populate it from database, but how do I create this structure in Ruby?

    • B Seven
      B Seven about 8 years
      I'm not sure if there is a good way to update JSON. Is it possible to work with it as a hash and then convert it to JSON when you are finished processing?
    • B Seven
      B Seven about 8 years
      You can use Hash#merge and #merge!. I think #merge! is faster and uses less memory because it does not need to duplicate the data. See ruby-doc.org/core-2.2.0/Hash.html#method-i-merge
    • user984621
      user984621
      Yeah that should not be a problem as the final structure will look like above. I tried it through a hash, but I failed at concatenating hash items.