Question

I am trying to write/append some data in a JSON file using ruby. I am facing issues while writing data in JSON file in proper format. I have created and stored my values in temphash. I want to append the content of temphash in existing JSON file. I am doing it in following way:

 tempHash = {"Group_Name" => @GroupName, "Group_Logo_Code" => @GroupLogoCode }

 json = File.read('public/group.json')
 secondJsonArray = JSON.parse(json)
 secondJsonHash = Hash[*secondJsonArray]

 jsonHash = []  
 jsonHash << secondJsonHash
 jsonHash << tempHash      

 File.open("public/group.json","w") do |f|
  f.puts JSON.pretty_generate(jsonHash)
 end 

This is creating malformed JSON. I am not getting the JSON in expected format

Below is what I expect:

[ 
 {
  "Group_Name": "Group Name",
  "Group_Logo_Code": "Group Logo code"
 },
 {
  "Group_Name": "Group Name",
  "Group_Logo_Code": "Group Logo code"
 },
 {
  "Group_Name": "Group Name",
  "Group_Logo_Code": "Group Logo code"
 },
]    

Below is what I am getting:

[
  {
    "{\"{\\\"Group_Name\\\"=>\\\"Group Name\\\", \\\"Group_Logo_Code\\\"=>\\\"Group Logo code\\\"}\"=>{\"Group_Name\"=>\"Group Name\", \"Group_Logo_Code\"=>\"Group Logo code\"}}": {
  "Group_Name": "Group Name",
  "Group_Logo_Code": "Group Logo code"
    }
   },
  {
    "Group_Name": "Group Name",
    "Group_Logo_Code": "Group Logo code"
  }
]

Please let me know if there is any better way to do this. Can anyone please help me resolve this issue. Thanks in advance.

Was it helpful?

Solution

Uri Agassi's code is perfect, but I thought to explain what went wrong in the OP code.

The Hash[] expects an array of key, value pairs (either as separate arguments or an array of arrays):

Hash[:a, 1, :b, 2]        # => {:a=>1, :b=>2}
Hash[[[:a,1], [:b,2]]]    # => {:a=>1, :b=>2}

But the original JSON contained Array of Hashes which gets parsed into corresponding Ruby objects as in the simplified case:

[{:a => 1}, {:b => 2}]

When you use the Ruby splat operator * on the above array:

Hash[ *[{:a => 1}, {:b => 2}] ]

You efectively provide separate hashes as a key-value pair to the Hash constructor:

Hash[ {:a => 1}, {:b => 2} ]  # => {{:a=>1} => {:b=>2}}

So, essentially, you got what you asked for: you turned a array of hashes into a hash of hashes and then you added that to a blank array and topped up with another hash.

Correct solution

Just to make the original code work with minimal changes (but still take a look at Uri's solution):

tempHash = {"Group_Name" => @GroupName, "Group_Logo_Code" => @GroupLogoCode }

json = File.read('public/group.json')
secondJsonArray = JSON.parse(json)

secondJsonArray << tempHash

File.open("public/group.json","w") do |f|
  f.puts JSON.pretty_generate(secondJsonArray)
end

OTHER TIPS

It seems that you are doing much too much in this code - why are you trying to convert the array to a hash? Leave it as an array:

tempHash = {"Group_Name" => @GroupName, "Group_Logo_Code" => @GroupLogoCode }

json = File.read('public/group.json')

File.open("public/group.json","w") do |f|
  f.puts JSON.pretty_generate(JSON.parse(json) << tempHash)
end 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top