From 6de4713d38863109e255b809a11a902b8b821b82 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 1 Mar 2013 23:11:44 -0500 Subject: [PATCH] Extract top projects query object This removed a bit of duplication from the stats controller. --- app/controllers/stats_controller.rb | 31 ++------------------ app/models/stats/top_projects_query.rb | 39 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 29 deletions(-) create mode 100644 app/models/stats/top_projects_query.rb diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index e4e46fb7..b3557a1d 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -499,35 +499,8 @@ class StatsController < ApplicationController end def get_stats_projects - # get the first 10 projects and their action count (all actions) - # - # Went from GROUP BY p.id to p.name for compatibility with postgresql. Since - # the name is forced to be unique, this should work. - @projects_and_actions = current_user.projects.find_by_sql( - "SELECT p.id, p.name, count(*) AS count "+ - "FROM projects p, todos t "+ - "WHERE p.id = t.project_id "+ - "AND t.user_id=#{current_user.id} " + - "GROUP BY p.id, p.name "+ - "ORDER BY count DESC " + - "LIMIT 10" - ) - - # get the first 10 projects with their actions count of actions that have - # been created or completed the past 30 days - - # using GROUP BY p.name (was: p.id) for compatibility with Postgresql. Since - # you cannot create two contexts with the same name, this will work. - @projects_and_actions_last30days = current_user.projects.find_by_sql([ - "SELECT p.id, p.name, count(*) AS count "+ - "FROM todos t, projects p "+ - "WHERE t.project_id = p.id AND "+ - " (t.created_at > ? OR t.completed_at > ?) "+ - "AND t.user_id=#{current_user.id} " + - "GROUP BY p.id, p.name "+ - "ORDER BY count DESC " + - "LIMIT 10", @cut_off_month, @cut_off_month] - ) + @projects_and_actions = Stats::TopProjectsQuery.new(current_user).result + @projects_and_actions_last30days = Stats::TopProjectsQuery.new(current_user, @cut_off_month).result # get the first 10 projects and their running time (creation date versus # now()) diff --git a/app/models/stats/top_projects_query.rb b/app/models/stats/top_projects_query.rb new file mode 100644 index 00000000..1ed70f44 --- /dev/null +++ b/app/models/stats/top_projects_query.rb @@ -0,0 +1,39 @@ +# Get the first 10 projects with their actions count of actions. +# When a cutoff is passed in, only actions that have been created +# or completed since that cutoff will be included. +module Stats + class TopProjectsQuery + + attr_reader :user, :cutoff + def initialize(user, cutoff = nil) + @user = user + @cutoff = cutoff + end + + def result + user.projects.find_by_sql(query_options) + end + + private + + def query_options + options = [sql, user.id] + options += [cutoff, cutoff] if cutoff + options + end + + def sql + query = "SELECT p.id, p.name, count(p.id) AS count " + query << "FROM todos t, projects p " + query << "WHERE t.project_id = p.id " + query << "AND t.user_id= ? " + if cutoff + query << "AND (t.created_at > ? OR t.completed_at > ?) " + end + query << "GROUP BY p.id, p.name " + query << "ORDER BY count DESC " + query << "LIMIT 10" + end + + end +end