0

I have the following controller code:

def calculate_quote

  @mouldings = Moulding.find( params[:id].split(","), :select => 'id, cost, width' )
  @mouldings.collect! do |moulding|
    { "moulding_id_#{moulding.id}" => { :cost => moulding.cost, :width => moulding.width } }
  end
  @material_costs = MaterialCost.all
  @material_costs.collect! do |material_cost|
    { material_cost.material.gsub(" ", "_").downcase => { :cost => material_cost.cost_per_square_mm } }
  end
  @app_options = AppOption.all
  @app_options.collect! do |app_option|
    { app_option.name.gsub(" ", "_").downcase => { :value => app_option.value } }
  end

  respond_to do |format|
    format.json { render :json => { :mouldings => @mouldings, :material_costs => @material_costs, :app_options => @app_options } }
  end
end

And this gives me the following JSON output:

{"mouldings":[{"moulding_id_2":{"cost":"3.1","width":45}},{"moulding_id_4":{"cost":"1.5","width":30}},{"moulding_id_6":{"cost":"2.1","width":50}}],"material_costs":[{"mountboard":{"cost":"0.00000246494303242769"}},{"glass":{"cost":"0.0000032426589803639"}},{"backing_board":{"cost":"0.00000135110790848496"}}],"app_options":[{"vat":{"value":"17.5"}},{"wastage":{"value":"20"}},{"markup":{"value":"3"}}]}

I want to format the JSON output so I can use jQuery to extract the data using the following sort of syntax:

data.mouldings.moulding_id_2.cost

How would I change the controller to achieve this?

2 Answers 2

1

Let's try rethinking the way you're constructing your data. In my opinion, it doesn't make a whole lot of sense to use ids as object indexes. Instead, why not do something like this:

@mouldings = Moulding.find( params[:id].split(","), :select => 'id, cost, width' )
@mouldings.collect! do |moulding|
  { :id => moulding.id, :cost => moulding.cost, :width => moulding.width }
end

This way, you should have an array of objects containing all the data you need for that moulding. In jQuery, you can then iterate over this array and grab all the information you need, like this:

$.each(data.mouldings, function(index, moulding) {
    alert("This moulding has an id of " + moulding.id + " and costs " + moulding.cost);
});

I think this makes a lot more sense than explicitly calling:

data.mouldings.moulding_id_2.cost

If you want to find the exact moulding_id #2, then you should iterate over your dataset as I showed above, and perform a check like this:

if (moulding.id == 2) {//do something};
Sign up to request clarification or add additional context in comments.

2 Comments

I want to use all the data in the JSON feed to perform a calculation on the client. Surely is it not easier to get the data using something like data.mouldings.moulding_id_2.cost and data.material_costs.mountboard.cost rather than doing multiple loops through the data?
@freshest yes, it certainly would be faster, but it would also mean hard-coding the IDs into your JavaScript. If your data ever changes, you'll be glad for the loop. At the same time, if you only have 3 or 4 mouldings in the array, the speed difference on all computers built after 1998 will be entirely unnoticeable. If you know your data isn't going to change and performance really is an issue, naturally, your way works better.
0

At the moment, mouldings is a list of singleton hashes. You want it to be a single hash mapping ids to detail hashes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.