Reputation: 12066
I am wondering how I can make this work. Assuming I have a model of Project that belongs_to a Client. I want to output those particular projects to JSON, but they need to be grouped by their client. I thought this would work:
@projects.group_by(&:client).to_json
That ALMOST works, except the to_json method isn't calling .to_json on the client, so for the client you get this in your JSON:
"#<Client:0x1051d4fb0>":[{ "project":{"name":"My Only Project", "client_id":1}}]
But I really need it like this:
{"client":{"name":"Home Workers Unite", "id":1, "projects":[{"name":"My Only Project","client_id":1}]}}
Any help is appreciated!
Upvotes: 2
Views: 1999
Reputation: 10907
As already told by @LarryK, the json you want as out put is not a valid json. In json keys can only be strings unlike ruby which can has objects as keys. Also, I would suggest that the json response be more like following:
{clients: [
{
"name":"Home Workers Unite",
"id":1,
"projects": [
{"name":"My First Project", "id":1},
{"name":"My Second Project", "id":2}
]
}
]
}
You already have projects available with you. You also have the code to group them by client, but a simple to_json
on the resulting hash would not be suitable here. You would need to manipulate the grouped response further to be able to directly use to_json
:
results = {clients: []}
@projects.group_by(&:client).each do |client, projects|
results[:clients] << {
id: client.id,
name: client.name
projects: projects
}
end
results.to_json
This is ruby/rails version of the solution. However if you have a json heavy application, I would suggest using some gem(jbuilder, rabl, or any other) to create the desired responses.
PS: code is not tested
Upvotes: 3
Reputation: 49104
The json in your orig post is not valid json since you don't have a property name for the array of projects.
Look into the acts_as_api suggestion from Murifox and other api techniques from railscasts--he just did one recently.
If your api user only wants one client at a time, you can use a json structure such as:
{client: {"name":"Home Workers Unite", "id":1},
projects: [
{"name":"My Only Project", "client_id":1}
]
}
Or you can send a subset (or all) of the needed client and project info:
{clients: [
{"name":"Home Workers Unite", "id":1},
{"name":"Factory Workers Unite", "id":2},
],
projects: [
{"name":"My Only Project", "client_id":1},
{"name":"Project 2", "client_id":2},
{"name":"Project 3", "client_id":2}
]
}
Benefit: fewer roundtrips from the server to the api client.
Upvotes: 0
Reputation: 15089
I recommend you to take a look at the gem acts_as_api. It makes it very easy to manipulate your objects as JSON.
Upvotes: 1