Sebastian Zeki
Sebastian Zeki

Reputation: 6874

How to reformat JSON in rails

I am trying out d3.js from a rails app to give me pretty graphs. One of the graphs I am trying out is a forced directed graph. In order to create this the JSON needs to be in the format

{
  "nodes":[
    {"name":"Myriel"},
    {"name":"Napoleon"},
    {"name":"Mlle.Baptistine"},
    {"name":"Mme.Magloire"}
 ],
"links":[
    {"source":1,"target":0,"value":1},
    {"source":2,"target":0,"value":8},
    {"source":3,"target":0,"value":10},
    {"source":3,"target":2,"value":6}
]
}

I currently have produced JSON from my database using this query:

 User.joins("INNER JOIN relationships ON users.id = relationships.user_id").select(" users.name, relationships.source, relationships.target,relationships.value")

which was created in the controller as follows

 def index
       render :json =>  User.joins("INNER JOIN relationships ON users.id = relationships.user_id").select(" users.name, relationships.source, relationships.target,relationships.value")
  end
end

and the result looks like this:

[{"name":"Myriel","source":121,"target":1,"value":1},{"name":"Napoleon","source":119,"target":2,"value":2},    {"name":"Myriel","source":121,"target":1,"value":2},{"name":"Myriel","source":121,"target":3,"value":1},{"name":"Mlle.Baptistine","source":122,"target":2,"value":3}]

Is there a simple way to map my JSON to what I need?

Upvotes: 0

Views: 111

Answers (2)

Surya
Surya

Reputation: 15992

As suggested in another answer, create a class method:

class User
  def self.including_relationships
    User.joins("INNER JOIN relationships ON users.id = relationships.user_id").select("users.name, relationships.user_id, relationships.target,relationships.value").each_with_object(Hash.new{|h, k| h[k] = []}) do |a, obj| 
      obj['nodes'] << a.slice('name')
      obj['links'] << a.slice('source', 'target', 'value')
    end
  end
end

Then in your controller:

def index
  render :json =>  User.including_relationships
end

I named method as including_relationships since it is not really creating a JSON instead converting the data into a Hash object, you can name it as you wish.

Upvotes: 1

raviture
raviture

Reputation: 1059

You can write a class method for User model and that method will return the json as you need.

def get_json
  json_data = User.joins("INNER JOIN relationships ON users.id = relationships.user_id").select(" users.name, relationships.user_id, relationships.target,relationships.value")

  {
    'nodes' => json_data.collect {|json| json.slice('name')},
    'links' => json_data.collect {|json| json.slice('source', 'target', 'value')}
  }
end

Upvotes: 2

Related Questions