2010-12-07 19 views
5

tengo el siguiente controlador:Ruby on Rails - Render JSON

@moulding = Moulding.find(params[:id].split(","), :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 

La salida JSON es el siguiente:

{"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"}}} 

Me gustaría que el JSON para estar en el siguiente formato:

{"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"}}} 

La razón por la que quiero hacer esto es para poder extraer los datos de un particular moulding por id de la cadena JSON. ¿Cómo puedo reformatear el JSON renderizado?

Respuesta

3

En mi respuesta original, hice la suposición errónea de que @moulding era un objeto único, cuando en realidad se trataba de un conjunto de objetos. La respuesta habría funcionado en ese caso. Para hacer lo que quiere para las molduras, tendrá que volver a embalar el conjunto de objetos. Que se vería así:

@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 

El método collect itera sobre todos los elementos en el conjunto de molduras que tiene, y poner el valor de retorno en una nueva matriz para usted. El método collect! hace esto en su lugar (modifica la matriz en la que está trabajando). Si quieres asignarlo a una nueva variable, está bien.

Esencialmente, di vuelta los objetos de moldeo en conjuntos de hashes. El resultado final se vería como tú quisieras.


vieja respuesta:

Parece ser que lo que quiere hacer es cambiar la clave :moulding en el código para la identificación del elemento. Ejemplo:

format.json { render :json => { @moulding.id => @moulding, :mount => @mount, :glass => @glass, :backing_board => @backing_board, :vat => @vat, :wastage => @wastage, :markup => @markup } } 

no estoy exactamente seguro de cómo suprimir el ID de la parte superior de la cabeza, pero la repetición de la ID no debe doler nada.

NOTA: El nombre de la clave de moldeo está utilizando el prefijo @ en lugar del símbolo que estaba allí antes. Es un detalle muy sutil y fácil de pasar por alto.

+0

@Berin Loritsch - El uso de '@ moulding.id' da un error' método indefinido 'id''. – freshest

+0

¿Estás seguro de que tienes '@' en vez de ':'? Esperaría que ': moulding.id' arrojara ese error. –

+0

@Berin Loritsch - Sí, estoy usando '@moulding.id => @ moulding' – freshest