From 31c7a43a18e72d0d7fd4285ee539543dbfc7b4bc Mon Sep 17 00:00:00 2001 From: Petko Bordjukov Date: Mon, 10 Oct 2016 21:28:23 +0300 Subject: [PATCH] Add a Summary and Ranking --- app/controllers/summaries_controller.rb | 11 ++++++ app/models/ranking.rb | 45 +++++++++++++++++++++++++ app/models/summary.rb | 15 +++++++++ app/views/summaries/show.json.jbuilder | 1 + config/routes.rb | 1 + 5 files changed, 73 insertions(+) create mode 100644 app/controllers/summaries_controller.rb create mode 100644 app/models/ranking.rb create mode 100644 app/models/summary.rb create mode 100644 app/views/summaries/show.json.jbuilder diff --git a/app/controllers/summaries_controller.rb b/app/controllers/summaries_controller.rb new file mode 100644 index 0000000..1a005e2 --- /dev/null +++ b/app/controllers/summaries_controller.rb @@ -0,0 +1,11 @@ +class SummariesController < ApplicationController + def show + @summary = Summary.new summary_params + end + + private + + def summary_params + params.require(:summary).permit(talk_ids: []) + end +end diff --git a/app/models/ranking.rb b/app/models/ranking.rb new file mode 100644 index 0000000..e265285 --- /dev/null +++ b/app/models/ranking.rb @@ -0,0 +1,45 @@ +RankingEntry = Struct.new :talk_id, :votes, :place + +class Ranking + include ActiveModel::Model + + attr_accessor :talk_ids + + def ranking + @ranking ||= ranking_data.map do |talk_id, votes, place| + RankingEntry.new talk_id, votes, place + end + end + + def [](talk_id) + ranking[talk_id] + end + + def talk_ids + @talk_ids ||= [] + end + + private + + def ranking_data + vote_data.sort_by { |_, votes| -votes } + .group_by { |_, votes| votes } + .each_with_index.map do |votes, placement| + votes.last.map {|talk_vote_data| talk_vote_data << placement + 1 } + end.flatten(1) + end + + def vote_data + blank_vote_data.merge(database_vote_data) + end + + def blank_vote_data + talk_ids.map do |talk_id| + [talk_id, 0] + end.to_h + end + + def database_vote_data + SelectedTalk.group(:talk_id).where(talk_id: @talk_ids).count + end +end diff --git a/app/models/summary.rb b/app/models/summary.rb new file mode 100644 index 0000000..d38bb7d --- /dev/null +++ b/app/models/summary.rb @@ -0,0 +1,15 @@ +class Summary + include ActiveModel::Model + + attr_accessor :talk_ids + + def number_of_ballots + @number_of_ballots ||= TalkPreference.joins(:selected_talks) + .where(selected_talks: {talk_id: @talk_ids}) + .uniq.count + end + + def ranking + @ranking ||= Ranking.new(talk_ids: talk_ids).ranking + end +end diff --git a/app/views/summaries/show.json.jbuilder b/app/views/summaries/show.json.jbuilder new file mode 100644 index 0000000..3b996b8 --- /dev/null +++ b/app/views/summaries/show.json.jbuilder @@ -0,0 +1 @@ +json.extract! @summary, :number_of_ballots, :ranking diff --git a/config/routes.rb b/config/routes.rb index 3dd5b2e..b3b5bf3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do resources :talk_preferences, only: [:index, :show, :create, :update] root to: 'home#index' + resource :summary, only: :show # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end