I have Rails application that needs to retrieve data from a SOAP server outside of my control. It retrieves a list of users with statistics attached to them and returns the data as JSON.
Once that data is retrieved, I need to combine it with data retrieved from my Rails app database.
Once I have the JSON from the SOAP server in hand, I send it up to a Rails controller so that new values can be added to the JSON and then sent back to the view.
My problem is a very simple one. I can’t seem to read and iterate through the JSON once it’s in my controller.
JS from my view stat_data is the JSON received from the SOAP service
window.get_metrics = (stat_data) ->
update_loading_message 'Getting Metrics'
console.log stat_data
$.ajax '/tracking/get_metrics',
type: "POST"
data: client_data: stat_data
dataType: 'json'
success : (data) ->
console.log(data)
# populate_table(data)
Controller
@client_advisors = params[:client_data]
puts @client_advisors
# This is where I would do my other processing / model calls to get new data
render file: 'tracking/metrics_data.json.erb', content_type: 'application/json'
Output of puts @client_advisors
{
"0"=>
{
"personnel_id"=>"1495",
"personnel_name"=>"John Smith",
"statistic_x"=>"200"
},
"1"=>
{
"personnel_id"=>"5266",
"personnel_name"=>"John Candy",
"statistic_x"=>"300"
},
"2"=>{
... etc ...
}
}
tracking/metrics_data.json.erb
[
<%= puts '~~~~~~~~~~~~ PROCESSING JSON' %>
<% @client_advisors.each do |advisor| %>
<%= puts 'advisor::' %>
<%= puts advisor %>
<%= puts 'advisor.inspect::' %>
<%= puts advisor.inspect %>
{
... This is where my re-generated JSON would go
}
<% end %>
]
I ridiculously can’t seem to target a personnel_name or personnel_id in my metrics_data.json.erb. It’s outputting each full advisor object just fine in the console… But I’m not sure what I should be using to target the object’s values. I’ve tried advisor.personnel_name (obviously won’t work because the objects are named "0, 1, 2, etc"), advisor['0'], advisor[0], advisor[:0]. None allow me to go a level deeper and retrieve the personnel_name.
Your time is most appreciated!
Solved!
Thanks to @willglynn
"jQuery – somewhat surprisingly – has no mechanism to create JSON. It can parse just fine, but you have to encode it yourself. You can use JSON.stringify , but for ahem certain browsers, you need JSON2.js" – @willglynn
Updated JS
window.get_metrics = (stat_data) ->
update_loading_message 'Getting Metrics'
console.log stat_data
$.ajax '/tracking/get_metrics',
type: "POST"
data: client_data: JSON.stringify(stat_data)
dataType: 'json'
success : (data) ->
console.log(data)
# populate_table(data)
Updated controller
@client_advisors = JSON.parse(params[:client_data])
Updated tracking/metrics.erb.json
<% puts advisor %>
<% puts advisor['personnel_id'] %>
To answer your question, when Rails gets a
POSTof JSON content, it transforms the request content into something looking like a form submission. This means thatparams[]won’t exactly match the original object. To get the original object back, you need to go behind Rails’ back and parse it out of the request directly:That said, there are a number of things I would change about this code.
erbtemplate. This is error-prone and tedious. Instead, userender :json => [{ 'key' => 'value' }].That last one is important, since it would let you eliminate your view and reduce the controller to something like:
See Skinny Controller, Fat Model for more.