From ccaa2e1a77ea3208356fe251d20bbe0ffed8fd4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 10 Dec 2018 16:33:04 +0100 Subject: [PATCH 1/5] Remove duplication to calculate percentage --- app/helpers/stats_helper.rb | 5 ----- app/models/budget/stats.rb | 5 ----- app/models/concerns/statisticable.rb | 7 +++++++ app/models/poll/stats.rb | 1 - 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb index 5dabd3f82..1bacf1139 100644 --- a/app/helpers/stats_helper.rb +++ b/app/helpers/stats_helper.rb @@ -30,9 +30,4 @@ module StatsHelper opt[:data][:graph] = admin_api_stats_path(budget_investments: true) content_tag :div, "", opt end - - def calculate_percentage(fraction, total) - percent = fraction / total.to_f - percent.nan? ? 0.0 : (percent * 100).round(3) - end end diff --git a/app/models/budget/stats.rb b/app/models/budget/stats.rb index cbcde4703..6315ca50e 100644 --- a/app/models/budget/stats.rb +++ b/app/models/budget/stats.rb @@ -188,11 +188,6 @@ class Budget::Stats calculate_percentage(participants, population) end - def calculate_percentage(fraction, total) - percent = fraction / total.to_f - percent.nan? ? 0.0 : (percent * 100).round(3) - end - def supports(supportable) ActsAsVotable::Vote.where(votable_type: "Budget::Investment", votable_id: supportable.investments.pluck(:id)) end diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 0a8032e3d..7759b631f 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -11,6 +11,13 @@ module Statisticable def generate self.class.stats_methods.map { |stat_name| [stat_name, send(stat_name)] }.to_h end + + private + + def calculate_percentage(fraction, total) + percent = fraction / total.to_f + percent.nan? ? 0.0 : (percent * 100).round(3) + end end class_methods do diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb index 2b40f2daf..ebba64b35 100644 --- a/app/models/poll/stats.rb +++ b/app/models/poll/stats.rb @@ -1,6 +1,5 @@ class Poll::Stats include Statisticable - include StatsHelper alias_method :poll, :resource def self.stats_methods From 04c920c27d9fc2c3507827b0db6050b3845893a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 10 Dec 2018 16:35:43 +0100 Subject: [PATCH 2/5] Simplify calculate percentage method --- app/models/concerns/statisticable.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 7759b631f..4f6072a81 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -15,8 +15,9 @@ module Statisticable private def calculate_percentage(fraction, total) - percent = fraction / total.to_f - percent.nan? ? 0.0 : (percent * 100).round(3) + return 0.0 if total.zero? + + (fraction * 100.0 / total).round(3) end end From 5d2f5d1d81ab81c929648c3c1e7a6f95d740ec1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 10 Dec 2018 18:08:05 +0100 Subject: [PATCH 3/5] Move gender and age methods to a common concern These are generic methods which only depend on the participants. --- app/models/budget/stats.rb | 48 ---------------------------- app/models/concerns/statisticable.rb | 48 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/app/models/budget/stats.rb b/app/models/budget/stats.rb index 6315ca50e..d2226630a 100644 --- a/app/models/budget/stats.rb +++ b/app/models/budget/stats.rb @@ -48,54 +48,10 @@ class Budget::Stats budget.investments.unfeasible.count end - def total_male_participants - participants.where(gender: "male").count - end - - def total_female_participants - participants.where(gender: "female").count - end - def total_supports supports(budget).count end - def total_unknown_gender_or_age - participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count - end - - def age_groups - groups = Hash.new(0) - ["16 - 19", - "20 - 24", - "25 - 29", - "30 - 34", - "35 - 39", - "40 - 44", - "45 - 49", - "50 - 54", - "55 - 59", - "60 - 64", - "65 - 69", - "70 - 140"].each do |group| - start, finish = group.split(" - ") - group_name = (group == "70 - 140" ? "+ 70" : group) - groups[group_name] = User.where(id: participants) - .where("date_of_birth > ? AND date_of_birth < ?", - finish.to_i.years.ago.beginning_of_year, - start.to_i.years.ago.end_of_year).count - end - groups - end - - def male_percentage - total_male_participants / total_participants_with_gender.to_f * 100 - end - - def female_percentage - total_female_participants / total_participants_with_gender.to_f * 100 - end - def participants User.where(id: (authors + voters + balloters + poll_ballot_voters).uniq.compact) end @@ -116,10 +72,6 @@ class Budget::Stats budget&.poll ? budget.poll.voters.pluck(:user_id) : [] end - def total_participants_with_gender - participants.where.not(gender: nil).distinct.count - end - def balloters_by_heading(heading_id) stats_cache("balloters_by_heading_#{heading_id}") do budget.ballots.joins(:lines).where(budget_ballot_lines: {heading_id: heading_id}).pluck(:user_id) diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 4f6072a81..4f83c2e74 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -14,6 +14,54 @@ module Statisticable private + def total_participants_with_gender + participants.where.not(gender: nil).distinct.count + end + + def total_male_participants + participants.where(gender: "male").count + end + + def total_female_participants + participants.where(gender: "female").count + end + + def total_unknown_gender_or_age + participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count + end + + def male_percentage + calculate_percentage(total_male_participants, total_participants_with_gender) + end + + def female_percentage + calculate_percentage(total_female_participants, total_participants_with_gender) + end + + def age_groups + groups = Hash.new(0) + ["16 - 19", + "20 - 24", + "25 - 29", + "30 - 34", + "35 - 39", + "40 - 44", + "45 - 49", + "50 - 54", + "55 - 59", + "60 - 64", + "65 - 69", + "70 - 140"].each do |group| + start, finish = group.split(" - ") + group_name = (group == "70 - 140" ? "+ 70" : group) + groups[group_name] = User.where(id: participants) + .where("date_of_birth > ? AND date_of_birth < ?", + finish.to_i.years.ago.beginning_of_year, + start.to_i.years.ago.end_of_year).count + end + groups + end + def calculate_percentage(fraction, total) return 0.0 if total.zero? From 1a86f7dbe819d872e6e769f22b28373cd7862670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Wed, 12 Dec 2018 17:05:26 +0100 Subject: [PATCH 4/5] Simplify total participants view logic --- app/views/polls/stats.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index a89277ac4..d472ebc3d 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -86,7 +86,7 @@ <%= @stats[:total_participants_booth] %> (<%= @stats[:total_participants_booth_percentage].round(2) %>%) - <%= @stats[:total_participants_web] + @stats[:total_participants_booth] %> + <%= @stats[:total_participants] %> From e4a032ee68cd2802217e0c9ae921d294857abbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Thu, 13 Dec 2018 12:40:41 +0100 Subject: [PATCH 5/5] Split common and specific stats methods --- app/models/budget/stats.rb | 10 +++++----- app/models/concerns/statisticable.rb | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/budget/stats.rb b/app/models/budget/stats.rb index d2226630a..24ba6fafc 100644 --- a/app/models/budget/stats.rb +++ b/app/models/budget/stats.rb @@ -3,11 +3,11 @@ class Budget::Stats alias_method :budget, :resource def self.stats_methods - %i[total_participants total_participants_support_phase total_participants_vote_phase - total_budget_investments total_votes total_selected_investments - total_unfeasible_investments total_male_participants total_female_participants - total_supports total_unknown_gender_or_age age_groups male_percentage - female_percentage headings total_participants_web total_participants_booths] + super + + %i[total_participants_support_phase total_participants_vote_phase + total_budget_investments total_votes total_selected_investments + total_unfeasible_investments total_supports headings + total_participants_web total_participants_booths] end private diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 4f83c2e74..6548df8c6 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -70,6 +70,12 @@ module Statisticable end class_methods do + def stats_methods + %i[total_participants total_male_participants + total_female_participants total_unknown_gender_or_age + male_percentage female_percentage age_groups] + end + def stats_cache(*method_names) method_names.each do |method_name| alias_method :"raw_#{method_name}", method_name