Reputation: 239
I'm looking to return some data for a json request in rails and I was wondering if the data being returned is malformed. Here is a shortened example:
[{"company":{"name":"A"}},{"company":{"name":"B"}}]
I always thought that when returning json it should describe the root element and plurals, so it should return something more like:
{"companies":[{"name":"A"},{"name":"B"}]}
Here are the questions - Is there any way I can get my json to come out in that format? Is that even the correct format or does each company node need to be labeled as well? Do I have to create a custom view to get my results? What is the best way to get jQuery to loop the data in the current format? Right now I'm using:
format.json { render :json => @companies.to_json() }
To render the results.
Thanks in advance for any help/advice.
Upvotes: 2
Views: 635
Reputation: 35505
You're probably looking for something like the JSend specification. I came up with this myself before I realized it had been done before, because I've found it tremendously useful to have a standard response container for JSON services.
Here's how I would rewrite your server response:
format.json do
render :json => {
:status => 'success',
:data => {
:companies => @companies
}
}
end
There are times when you need to alter the attributes that are generated when converted to JSON
. In these cases, I just use map
:
format.json do
render :json => {
:status => 'success',
:data => {
:companies => @companies.map do |company|
hash = company.attributes
hash['address'] = company.address
hash.delete('secret')
hash
end
}
}
end
A little more verbose than to_json
, but it's more flexible and works just as well in Rack middleware.
Upvotes: 4
Reputation: 284816
Both are valid JSON. However, I would agree with you that the second is preferable. It's less redundant, since the first has an unnecessary object layer and repeats the company key. But a more subtle benefit is that the second protects you from JSON hijacking, which is only possible when the root structure is an array.
To loop the first, use e.g.
$.getJSON(url, functon(resp)
{
for(var i = 0; i < resp.length; i++)
{
var company = resp[i].company;
var name = company.name;
}
});
Upvotes: 1