I am current working on formatting some data from ruby into json;
My current code looks like this
def line_chart_data
#sources = ['Facebook','Twitter','Instagram','LinkedIn']
#sourceCount = [5,12,16,6]
#weeks = ['one','two','three','four','five','six']
h = []
#weeks.each do |i,v|
h.push({'v' => 'Week ' + i})
#sourceCount.each do |s|
h.push({'v' => s})
end
end
c = {c: h}
#How the data should be formatted on export
#sources2 = {
cols: [
{label: 'Week', type: 'string'},
#Each Source needs to be looped though and formatted
{label: 'Facebook', type: 'number'},
{label: 'Twitter', type: 'number'},
{label: 'Instagram', type: 'number'},
{label: 'LinkedIn', type: 'number'}
],
rows: c
}
respond_to do |format|
format.js {render json: #sources2}
end
end
when the data gets printed to the console it looks like this (shortened it a little for brevity)
"rows":{"c":[{"v":"Week one"},{"v":5},{"v":12},{"v":16},{"v":6},
{"v":"Week two"},{"v":5},{"v":12},{"v":16},{"v":6},
{"v":"Week three"},{"v":5},{"v":12},{"v":16},{"v":6}]}
If you notice the first "c" opens with an array but as it loops through the above code it does not create a new array for each week. The code should look more like this.
"rows":{"c":[{"v":"Week one"},{"v":5},{"v":12},{"v":16},{"v":6}],
{"c":[{"v":"Week two"},{"v":5},{"v":12},{"v":16},{"v":6}]},
{"c":[{"v":"Week three"},{"v":5},{"v":12},{"v":16},{"v":6}]}
Where each loop of weeks array creates a new hash with a key of "c" and a value of array.
any help pointing me in the right direction is greatly appreciated! Been stuck on this for quite a while.
You will need to re-work your code a bit to get this. The JSON you want is actually not valid, so this is the closest you can get:
"rows":[{"c":[{"v":"Week one"},{"v":5},{"v":12},{"v":16},{"v":6}],
{"c":[{"v":"Week two"},{"v":5},{"v":12},{"v":16},{"v":6}]},
{"c":[{"v":"Week three"},{"v":5},{"v":12},{"v":16},{"v":6}]}]
Code:
rows = []
#weeks.each do |i,v|
h = []
h.push({'v' => 'Week ' + i})
#sourceCount.each do |s|
h.push({'v' => s})
end
rows.push({"c" => h})
end
#How the data should be formatted on export
#sources2 = {
cols: [
{label: 'Week', type: 'string'},
#Each Source needs to be looped though and formatted
{label: 'Facebook', type: 'number'},
{label: 'Twitter', type: 'number'},
{label: 'Instagram', type: 'number'},
{label: 'LinkedIn', type: 'number'}
],
rows: rows
}
Related
My HTML looks like:
<%= column_chart #data, stacked: true %>
In my controller I created the data field:
#values = WorkingMonth.select("date_end","workload").where(personal_id: #current_employee.personal_id)
#values.each do |data|
#data = [
{
name: "Available",
data: []
},
{
name: "Workload",
data:[[data.date_end.strftime("%B"),data.workload]]
}
]
end
My problem is in #values there are more than only one value but it shows me only the last one. How can I use each do with this data field?
Thanks in advance
UPDATE:
I've changed my data field like:
#data = #values.map do |value|
#data = [
{name: "Available", data: []},
{name: "Workload", data:[[value.date_end.strftime("%B"),value.workload]]}
]
end
After changing the result looks like:
Column Chart
You should use map instead of each since you want convert #values array:
#data = #values.map do |value|
[
{ name: "Available", data: [] },
{ name: "Workload", data: [[value.date_end.strftime("%B"),value.workload]] }
]
end
I changed the way to think and stopped using .each/.map do. I've used "group" and "DATE_TRUNC". The answer to my problem looks like:
#data = [{name: "Workload", data: WorkingMonth.where(personal_id: #current_employee.personal_id).group("DATE_TRUNC('Month', date_end)").sum(:workload)}]
I have a PORO TutorProfileHandler that has a function json that returns a hash.
class TutorProfileHandler
def initialize(opts)
#profile = opts[:tutor_profile]
end
def json
tutor = #profile.tutor
return {
id: tutor.id,
first_name: tutor.first_name,
last_name: tutor.last_name.first + '.',
school: #profile.school,
avatar: #profile.avatar.url,
bio: #profile.bio,
academic_level: #profile.academic_level,
headline: #profile.headline,
major: #profile.major,
rate: #profile.rate,
rating: #profile.rating,
courses: JSON.parse(#profile.courses),
video_url: #profile.video_url
}
end
end
In my index_tutor_profiles.json.jbuilder, I would like to generate
{
tutor_profile: [{id: 1, ...}, {id: 2, ...}, ...],
tutor_sum: 20
}
However when I do this
json.tutor_profiles (#tutor_profiles) do |profile|
TutorProfileHandler.new({tutor_profile: profile}).json
end
json.tutor_sum #tutor_sum
It gives me an empty array for tutor_profiles.
However if I move everything from TutorProfileHandler.json to the jbuilder file, it works. How do I explicitly include the hash returned by TutorProfileHandler.json in the jbuilder array?
Note: This returns an array, but it creates a new key-value pair array:
json.tutor_profiles json.array(#tutor_profiles) do |profile|
TutorProfileHandler.new({tutor_profile: profile}).json
end
Result:
{
array: [{id: 1, ...}, {id: 2, ...}, ...],
tutor_profile: [],
tutor_sum: 20
}
There is a ugly approach:
json.tutor_profiles #tutor_profiles do |profile|
tmp_json = TutorProfileHandler.new({tutor_profile: profile}).json
json.(tmp_json, *(tmp_json.keys))
end
I think the best practise is directly nesting inside model. You can get more information from the its github page.
I have a few ActiveRecord objects like City, Country, State etc. My controller action is like (as a representative example):
def get_data
#data = {
cities: City.limit(2),
countries: Country.limit(2),
states: State.limit(2),
version: 1000
}
respond_with #data
end
I want to render a JSON like:
{
data: {
country: [{id: 1, name: 'a'}, {id: 2, name: 'b'}],
state: [{id: 1, name: 'p'}, {id: 2, name: 'q'}],
city: [{id: 1, name: 'x'}, {id: 2, name: 'y'}],
version: 1000
}
}
(Please note singular keys for collections, Please do not suggest changes to the JSON structure, as it is fixed.)
What should be the rabl template for this? I have been breaking my head on this for hours.
if i were you i will not even care to go to rabl template for this because what your are creating with this code:
#data = {
cities: City.limit(2),
countries: Country.limit(2),
states: State.limit(2),
version: 1000
}
is the final output , not the individual components.
you can just replace this with:
render :json => {
:data => {
cities: City.limit(2).map{ |c|{:id => c[:id] },
countries: Country.limit(2).map{ |c|{:id => c[:id] },
states: State.limit(2).map{ |c|{:id => c[:id] },
version: 1000
}
}
its not a best use case for rabl , but if you still want it to load via rabl this below code in the get_data.json.rabl will do just fine.
node :data do
{
:version_number => #data[:version_number],
:country => #data[:countries].map{ |c|{:id => c[:id] , :name => c[:name]} }
:state => #data[:states].map{ |s|{:id => s[:id] , :name => s[:name]} }
:city => #data[:city].map{ |c|{:id => c[:id] , :name => c[:name]} }
}
end
I have an article model (which belongs to a user) and holds the number of facebook_shares, linkedin_shares and twitter_shares. I'd like to sum the number of facebook/linkedin/twitter shares for each user's articles and return them into an array I can put into a chart.
This is how I'm currently doing it, returning the results in a =content_tag as per this Railcast:
= content_tag :div, "", id: "shares-chart", data: {shares:
[
{y: 'Tweets', a: #user.articles.sum(:twitter_shares)},
{y: 'Facebook', a: #user.articles.sum(:facebook_shares)},
{y: 'LinkedIn', a: #user.articles.sum(:linkedin_shares)}
]
}
But this seems like an ugly way. Is there a nicer way using .map? It's a function I can't figure out how to apply to columns, rather than records.
Maybe you want this:
In your User model:
def construct_data
[{"Tweets" => :twitter_shares}, {"Facebook" => :facebook_shares}, {"LinkedIn" => :linkedin_shares}].map do |h|
{y: h.keys.first, a: #user.articles.sum(h.values.first)}
end
end
In your controller action:
#chart_data = #user.construct_data
In your view:
= content_tag :div, "", id: "shares-chart", data: {shares: #chart_data}
I could use your helping creating a valid JSON object in Rails.
Here is an example of a valid JSON object that I'm using in the jQuery plugin: https://drew.tenderapp.com/kb/autosuggest-jquery-plugin
var data = {items: [
{value: "21", name: "Mick Jagger"},
{value: "43", name: "Johnny Storm"},
{value: "46", name: "Richard Hatch"},
{value: "54", name: "Kelly Slater"},
{value: "55", name: "Rudy Hamilton"},
{value: "79", name: "Michael Jordan"}]};
Within Rails I'm creating my object as follows:
#projects = Projects.all
#projectlist = Array.new
#projectlist << {
:items => #projects.map { |project|
{
:name => space.name,
:value => space.id
}
}
}
But this ends up outputting like so which ERRORs by the plugin:
[{"items":[{"value":74,"name":"XXXXXX"},{"value":71,"name":"XXXXXX"},{"value":70,"name":"XXXXXX"}]}]
Looks like there is a [] around the initial {} any idea why that's happening and how to build a valid JSON object?
Thanks!
Simply assign #projectlist to a Hash, like so:
EDIT After looking at the plugin's API, I've come to the conclusion that you need to convert your values to strings first:
#projects = Projects.all
#projectlist = {
:items => #projects.map { |project|
{
:name => space.name,
:value => space.id.to_s
}
}
}
Since you're initializing #projectlist to an Array and pushing the Hash onto it, you're getting those wrapping [] characters.