making a pie-chart of the user age in rails
So for thousands of users I'd definitely do this in the database. While the labels will probably need some massaging, you can start with a query like this:
User.group("date_trunc('year', age(dob))").count
This will result in a hash with entries that look something like this:
{
"00:00:00" => 3,
"1 year" => 5,
"2 years" => 8,
...
}
You can then do relabelling and group the year results into bins (e.g. 10-20) as needed. I wouldn't try to do this all in one line in your view - I'd make this a method either on the model or on a dedicated query object.
rails: accessing a table attribute and using group()
From your question I'm not entirely sure what you're trying to do, but it sounds like you're trying to chart the number of users per city - is that right? If so, you can get the statistics by doing something like
User.group('city_id').count
That will result in a has that has the users per city, but the label will be the city id, not the name. We can improve this by adding a join clause and grouping by the name:
User.joins(:city).group('cities.name').count
I think, based on your question, that this will give you what you want. (I've made a couple of assumptions about the column and table names here - city_id, cities).
Issue with filtering by age when Date of Birth is stored in Database
Let's say you want to find users between and including ages 18 and 20 as of today, and you're storing the DOB in a field called dob
.
A person exactly 18 years old today would have been born on Apr 6, 1995. And one who's turning 21 tomorrow would be born on Apr 7, 1993.
So you want users with DOB between and including Apr 5, 1993 and Apr 6, 1995.
18.years.ago.to_date
=> Thu, 06 Apr 1995
(20.years.ago + 1.day).to_date
=> Mon, 07 Apr 1993
You can use this now
User.where("dob >= ? AND dob <= ?", 20.years.ago + 1.day, 18.years.ago)
Group Users by Age Range in ruby
You want to build some SQL that looks like this:
select count(*),
case
when age between 10 and 14 then '10 - 14'
when age between 15 and 21 then '15 - 21'
-- ...
end as age_range
from users
where age between 10 and 120
group by age_range
In ActiveRecord terms, that would be:
# First build the big ugly CASE, we can also figure out the
# overall max and min ages along the way.
min = nil
max = nil
cases = AGE_RANGES.map do |r|
min = [r[:min], min || r[:min]].min
max = [r[:max], max || r[:max]].max
"when age between #{r[:min]} and #{r[:max]} then '#{r[:min]} - #{r[:max]}'"
end
# Then away we go...
age_ranges = Users.select("count(*) as n, case #{cases.join(' ')} end as age_range")
.where(:age => min .. max)
.group('age_range')
.all
That will leave you with an array of objects in age_ranges
and those objects will have n
and age_range
methods. If you want a Hash out of that, then:
age_ranges = Hash[age_ranges.map { |r| [r.age_range, r.n] }]
That won't include ranges that don't have any people in them of course; I'll leave that as an exercise for the reader.
Rails: Using groupdate & chartkick to create a cumulative user graph
Martin's answer was close, but I ended up using:
User.group_by_week(:created_at).order("week asc").count.map { |x,y| { x => (sum += y)} }.reduce({}, :merge)
To get weekly - notice the order("week asc") - it's what fixed it...
pie chart for an array in Ruby
Check out this part of their website https://chartkick.com/#data -
<%= pie_chart [["Football", 10], ["Basketball", 5]] %>
If you are using a database then do this -
Define it in the controller -
def index
@piechartdata = Sport.pluck(:name, :id)
end
That will give you exactly this format -
[["Football", 10], ["Basketball", 5]]
Then in your view -
<%= pie_chart @piechartdata %>
Related Topics
How to Give a Date a Background Color with Axlsx
Receving the Undefined Method 'Generators' Error
How to Multiply "5X3" String in Ruby
How to Prevent My Users to Read My Ruby Code
Rails: Upload a File or Store a Url
Fetching Second Row from CSV File in Ruby
How to Convert Timestamp with Ruby
Convert This Xml Request to a Proper Savon Request
Regex to Remove the Webpage Part of a Url in Ruby
Ruby, No Implicit Conversion of Symbol into Integer
How to Set Up These Crud Controller Actions for Has_Many_Polymorphs and an Error
Invalid Route Name, Already in Use: 'Admin_Root' (Argumenterror) - Failed Activeadmin Install
Emulating Int64 Overflows in Ruby
Ruby Before_Validation Triggers Infinite Loop of Call Back
Rails Undefined Method 'Errors' for Nil:Nilclass in Simple_Form