diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index a47826aa3..3360dc047 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -33,20 +33,7 @@ module Statisticable end def participants_by_age - age_groups.map do |start, finish| - users = participants.where("date_of_birth > ? AND date_of_birth < ?", - finish.years.ago.beginning_of_year, - start.years.ago.end_of_year) - - [ - "#{start} - #{finish}", - { - range: range_description(start, finish), - count: users.count, - percentage: calculate_percentage(users.count, total_participants) - } - ] - end.to_h + participants_by_age_for(participants) end def participants_by_geozone @@ -92,6 +79,30 @@ module Statisticable ] end + def participants_by_age_for(users, relative_to: :participants) + age_groups.map do |start, finish| + group_count = users.between_ages(start, finish).count + total_count = if relative_to == :participants + total_participants + else + send(relative_to, start, finish).count + end + + [ + "#{start} - #{finish}", + { + range: range_description(start, finish), + count: group_count, + percentage: calculate_percentage(group_count, total_count) + } + ] + end.to_h + end + + def participants_between_ages(from, to) + participants.between_ages(from, to) + end + def calculate_percentage(fraction, total) return 0.0 if total.zero? diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb index dda2f74c1..b9938df64 100644 --- a/app/models/poll/stats.rb +++ b/app/models/poll/stats.rb @@ -18,9 +18,11 @@ class Poll::Stats total_male_web total_male_booth total_male_mail total_female_web total_female_booth total_female_mail male_web_percentage male_booth_percentage male_mail_percentage - female_web_percentage female_booth_percentage female_mail_percentage] + female_web_percentage female_booth_percentage female_mail_percentage + web_participants_by_age booth_participants_by_age mail_participants_by_age] end + def total_participants total_participants_web + total_participants_booth end @@ -40,6 +42,11 @@ class Poll::Stats User.where(id: voters.where(origin: channel).pluck(:user_id)) end + define_method :"#{channel}_participants_by_age" do + participants_by_age_for(send(:"#{channel}_participants"), + relative_to: :participants_between_ages) + end + %i[male female].each do |gender| define_method :"total_#{gender}_#{channel}" do send(:"#{channel}_participants").public_send(gender).count diff --git a/app/models/user.rb b/app/models/user.rb index 948cc4082..3f67b4748 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,6 +72,13 @@ class User < ApplicationRecord string = "%#{search_string}%" where("username ILIKE ? OR email ILIKE ? OR document_number ILIKE ?", string, string, string) end + scope :between_ages, -> (from, to) do + where( + "date_of_birth > ? AND date_of_birth < ?", + to.years.ago.beginning_of_year, + from.years.ago.end_of_year + ) + end before_validation :clean_document_number diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index 7fdbed498..f30dc7175 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -15,7 +15,10 @@ <%= link_to t("stats.polls.by_channel"), "#stats_by_channel" %>
| <%= t("stats.age") %> | + <% Poll::Stats::CHANNELS.each do |channel| %> +<%= t("stats.polls.#{channel}") %> | + <% end %> +
|---|---|
| <%= @stats[:participants_by_age][age_range][:range] %> | + + <% Poll::Stats::CHANNELS.each do |channel| %> + <% group = @stats[:"#{channel}_participants_by_age"][age_range] %> +
+
+
+
+
+ <%= "#{group[:count]} (#{number_to_stats_percentage(group[:percentage])})" %>
+ |
+ <% end %>
+