开发者

Ruby on Rails - Render JSON

开发者 https://www.devze.com 2023-01-29 12:24 出处:网络
I have the following controller: @moulding = Moulding.find( params[:id].split(\",\"), :开发者_C百科select => \'id, cost, width\' )

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消