user3763682 user3763682 - 11 months ago 102
JSON Question

Getting data from Postgres in JSON format in ROR into a Highcharts javascript

I am learning ROR (5+ months currently) and am trying to get data from a Postgres database into Highcharts. The Postgres table has columns for :id, :name, and :pc1 - which is one-year percent change - (among others). There are five time-series [:id] in the database.

Here's the db schema:

create_table "series", force: true do |t|
t.string "acronym"
t.string "name"
t.string "current"
t.string "previous"
t.string "pc1"
t.datetime "created_at"
t.datetime "updated_at"
end


Here's a portion of the series controller:

class SeriesController < ApplicationController
before_action :set_series, only: [:show, :edit, :update, :destroy]

# GET /series
# GET /series.json
def index
@series = Series.all
end

def percent
@series.each do |series|
series.name
series.pc1
end
render :json
end


I'm defining a method - "percent" - because I want to create several different charts, e.g., one for year-over-year percent change (this one) as well as previous vs. current.

Here's the view with the Highcharts script:

More or less following Highcharts' instructions (here: http://www.highcharts.com/docs/working-with-data/preprocessing-data-from-a-database ), I pulled the "data" request out of the Highcharts function. The original Highcharts demonstration code - using an embedded "hard-coded" array - is here: http://www.highcharts.com/docs/getting-started/your-first-chart I assume I'm supposed to remove the series if I'm declaring it as a variable before calling the function. I'm ignoring the php in the example because I should be rendering the series in json from the controller.

<div>
<script>
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
series: [{

// I pulled local host out of here because Stackoverflow doesn't like it

var url = "";
$.getJSON(url, function(resp) {
options.series[0].name = name;
options.series[0].pc1 = pc1;
var chart = new Highcharts.Chart(options);
});

pointStart: 0,
pointInterval
}]
});

$(function () {

$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
});

});
</script>
</div>


Here's the model:

class Series < ActiveRecord::Base
has_many :series
end


I think I have multiple issues:


  1. Am I correctly rendering json in the controller?

  2. Should I be calling a url in the script or a file (since I'm using a localhost server)?

  3. I suspect there are others, e.g., should the percent method be in the before action in the controller?



The error in the console is this line: var url = "http://localhost:3000/series"; I've tried a number of variations including /series and the file path.

My environment is set-up (using an Apple Mac with Mavericks). I use the Terminal app with rails server running, Postgres running in a separate tab, Sublime Text version 2, and Chrome.

Answer Source

1. Am I correctly rendering json in the controller?

I don't think so. I would also send a status and you need to tell what json it is. So i would go like:

def percent
  @series.each do |series|
    series.name
    series.pc1
  end
  render status: 200, json: @series.as_json  
end

2. Should I be calling a url in the script or a file (since I'm using a localhost server)?

A url, always a url. You won't be able to access a file. And your url seems correct.

3. I suspect there are others, e.g., should the percent method be in the before action in the controller?

It depends on what you are doing. If you want to respond with the percent method generated json by calling /seriesroute, you need to call percent in the index method. If you want an explicit call to /percent you just need to add it to the routes and you are good to go. Btw, you did change the routes file for this, right? You should at least have a get available for the series controller, or if you want full CRUD, a resource should be there. Also, I think you should keep with the convention of having the model name on the singular form, and your has_many: series, doesn't make sense to me. What are you trying to achieve there? If a serie has_may series, then you should have a serie_id in the model and also a belongs to.

Hope this helps somehow.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download