From 4ee474a7d2568d7aec2b34ca2d66426046346938 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 28 Jan 2016 14:46:25 +0100 Subject: [PATCH] Speed up external user statistics --- app/controllers/external_users_controller.rb | 44 +++++++++++++++++++ app/views/external_users/statistics.html.slim | 8 ++-- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/app/controllers/external_users_controller.rb b/app/controllers/external_users_controller.rb index 26af4fbf..5c6619cb 100644 --- a/app/controllers/external_users_controller.rb +++ b/app/controllers/external_users_controller.rb @@ -14,9 +14,53 @@ class ExternalUsersController < ApplicationController authorize! end + def working_time_query + """ + SELECT user_id, + exercise_id, + max(score) as maximum_score, + count(id) as runs, + sum(working_time_new) AS working_time + FROM + (SELECT user_id, + exercise_id, + score, + id, + CASE + WHEN working_time >= '0:30:00' THEN '0' + ELSE working_time + END AS working_time_new + FROM + (SELECT user_id, + exercise_id, + max(score) AS score, + id, + (created_at - lag(created_at) over (PARTITION BY user_id, exercise_id + ORDER BY created_at)) AS working_time + FROM submissions + WHERE user_id = #{@user.id} + AND user_type = 'ExternalUser' + GROUP BY exercise_id, + user_id, + id) AS foo) AS bar + GROUP BY user_id, + exercise_id; + """ + end + def statistics @user = ExternalUser.find(params[:id]) authorize! + + statistics = {} + + ActiveRecord::Base.connection.execute(working_time_query).each do |tuple| + statistics[tuple["exercise_id"].to_i] = tuple + end + + render locals: { + statistics: statistics + } end end diff --git a/app/views/external_users/statistics.html.slim b/app/views/external_users/statistics.html.slim index 99662883..a8873cb3 100644 --- a/app/views/external_users/statistics.html.slim +++ b/app/views/external_users/statistics.html.slim @@ -10,9 +10,9 @@ h1 = t('.title') th.header = t(title) tbody - exercises.each do |exercise| - - submissions = @user.submissions.where(:exercise_id => exercise.id, :cause => ['submit', 'run']) + - if statistics[exercise.id] then stats = statistics[exercise.id] else stats = {"working_time" => 0, "runs" => 0, "score" => 0} tr td = link_to exercise, controller: "exercises", action: "statistics", external_user_id: @user.id, id: exercise.id - td = submissions.maximum(:score) or 0 - td = submissions.count - td = exercise.average_working_time_for_only(@user.id) or 0 + td = stats["maximum_score"] or 0 + td = stats["runs"] or 0 + td = stats["working_time"] or 0 diff --git a/config/locales/de.yml b/config/locales/de.yml index 683c1dff..9fd2dce0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -269,7 +269,7 @@ de: title: Statistiken für Externe Benutzer exercise: Übung score: Bewertung - runs: Versuche + runs: Abgaben worktime: Arbeitszeit files: roles: diff --git a/config/locales/en.yml b/config/locales/en.yml index 823fe864..f005eea2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -269,7 +269,7 @@ en: title: External User Statistics exercise: Exercise score: Score - runs: Runs + runs: Submissions worktime: Working Time files: roles: