class TartifletteScoringService def self.scored?(tartiflette, session) session[:scored_tartiflettes] ||= [] session[:scored_tartiflettes].include?(tartiflette.id) end def self.mark_as_scored(tartiflette, session) session[:scored_tartiflettes] ||= [] session[:scored_tartiflettes] << tartiflette.id unless scored?(tartiflette, session) end def self.submit_scores(tartiflette, scores, session) scores.each do |criterium_id, score_params| Score.create!( session_id: session.id, tartiflette: tartiflette, scoring_criterium_id: criterium_id, value: score_params[:value] ) end mark_as_scored(tartiflette, session) rescue ActiveRecord::RecordInvalid => e raise StandardError, "Failed to create score: #{e.message}" end def self.update_scores(tartiflette, scores, session) scores.each do |score_id, score_params| score = tartiflette.scores.find(score_id) score.update!(value: score_params[:value]) end rescue ActiveRecord::RecordInvalid => e raise StandardError, "Failed to update score: #{e.message}" end def self.average_score(tartiflette) tartiflette.scores.average(:value).to_f end def self.average_score_by_category(tartiflette) tartiflette .scores .group_by { |score| score.scoring_criterium.category } .transform_values do |scores| (scores.sum(&:value).to_f / scores.size).round(2) end end def self.total_score_by_category(tartiflette) tartiflette .scores .group_by { |score| score.scoring_criterium.category } .transform_values do |scores| (scores.sum(&:value).to_f / scores.size).round(2) end end def self.leaderboard Tartiflette .joins(:scores) .select("tartiflettes.*, SUM(scores.value) AS total_score") .group("tartiflettes.id") .order("total_score DESC") .map { |tartiflette| [ tartiflette, tartiflette.total_score.to_f ] } end end