Ruby on Rails - Render JSON
I have the following controller:
@moulding = Moulding.find( params[:id].split(","), :开发者_C百科select => 'id, cost, width' )
@mount = MaterialCost.find(1).cost_per_square_mm
@glass = MaterialCost.find(2).cost_per_square_mm
@backing_board = MaterialCost.find(3).cost_per_square_mm
@vat = AppOption.find( 1, :select => 'value' )
@wastage = AppOption.find( 2, :select => 'value' )
@markup = AppOption.find( 3, :select => 'value' )
respond_to do |format|
format.json { render :json => { :moulding => @moulding, :mount => @mount, :glass => @glass, :backing_board => @backing_board, :vat => @vat, :wastage => @wastage, :markup => @markup } }
end
The JSON output is as follows:
{"moulding":[{"moulding":{"cost":"3.1","id":2,"width":45}},{"moulding":{"cost":"1.5","id":4,"width":30}},{"moulding":{"cost":"2.1","id":6,"width":50}}],"mount":"0.00000246494303242769","glass":"0.0000032426589803639","backing_board":"0.00000135110790848496","vat":{"app_option":{"value":"17.5"}},"wastage":{"app_option":{"value":"20"}},"markup":{"app_option":{"value":"3"}}}
I would like the JSON to be in the following format:
{"mouldings":[{"2":{"cost":"3.1","width":45}},{"4":{"cost":"1.5","width":30}},{"6":{"cost":"2.1","width":50}}],"mount":"0.00000246494303242769","glass":"0.0000032426589803639","backing_board":"0.00000135110790848496","vat":{"app_option":{"value":"17.5"}},"wastage":{"app_option":{"value":"20"}},"markup":{"app_option":{"value":"3"}}}
The reason I want to do this is so I can extract the data for a particular moulding
by id
from the JSON string. How can I reformat the rendered JSON?
In my original answer, I made the mistaken assumption that @moulding was a single object, when in fact it was a set of objects. The answer would have worked in that case. To do what you want for the mouldings, you will have to repack the set of objects. That would look like this:
@moulding.collect! do |moulding|
{ moulding.id => {:cost=>moulding.cost, :width=>moulding.width}}
end
respond_to do |format|
format.json { render :json => { :moulding => @moulding, :mount => @mount, :glass => @glass, :backing_board => @backing_board, :vat => @vat, :wastage => @wastage, :markup => @markup } }
end
The collect
method will iterate over all the items in the set of mouldings you have, and put the return value into a new array for you. The collect!
method does this in place (modifies the array you are working on). If you want to assign it to a new variable, that's fine.
Essentially, I turned the moulding objects into sets of hashes. The final output would look like like you wanted.
old answer:
It appears that what you want to do is to change the :moulding
key in your code to the item id. Example:
format.json { render :json => { @moulding.id => @moulding, :mount => @mount, :glass => @glass, :backing_board => @backing_board, :vat => @vat, :wastage => @wastage, :markup => @markup } }
I'm not exactly sure how to suppress the ID off the top of my head, but repeating the ID shouldn't hurt anything.
NOTE: The moulding key name is using the @
prefix instead of the symbol that was there before. It is a very subtle and easily overlooked detail.
精彩评论