diff --git a/app/models/issue.rb b/app/models/issue.rb index 0b8a2b2..4c01c48 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -244,6 +244,7 @@ class Issue < ActiveRecord::Base @spent_hours = nil @total_spent_hours = nil @total_estimated_hours = nil + @last_updated_by = nil base_reload(*args) end @@ -1027,6 +1028,10 @@ class Issue < ActiveRecord::Base @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort) end + def last_updated_by + @last_updated_by + end + # Preloads relations for a collection of issues def self.load_relations(issues) if issues.any? @@ -1081,6 +1086,24 @@ class Issue < ActiveRecord::Base end end + # Preloads users who updated last a collection of issues + def self.load_last_updated_by(issues) + if issues.any? + journals_user = {} + issues_last_journal = Journal.joins(:issue).preload(:user). + where('issues.updated_on = journals.created_on'). + where(:journalized_id => issues.map(&:id)) + + issues_last_journal.each do |journal| + journals_user[journal.journalized_id] = journal.user + end + + issues.each do |issue| + issue.instance_variable_set "@last_updated_by", (journals_user[issue.id] || nil) + end + end + end + # Finds an issue relation given its id. def find_relation(relation_id) IssueRelation.where("issue_to_id = ? OR issue_from_id = ?", id, id).find(relation_id) @@ -1400,7 +1423,7 @@ class Issue < ActiveRecord::Base end Project.where(condition).having_trackers end - + # Returns a scope of trackers that user can assign the issue to def allowed_target_trackers(user=User.current) self.class.allowed_target_trackers(project, user, tracker_id_was) diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index f718e3e..528e3b5 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -31,6 +31,7 @@ class IssueQuery < Query QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true), QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true), QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'), + QueryColumn.new(:last_updated_by, :sortable => false), QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"), @@ -328,6 +329,9 @@ class IssueQuery < Query if has_column?(:total_spent_hours) Issue.load_visible_total_spent_hours(issues) end + if has_column?(:last_updated_by) + Issue.load_last_updated_by(issues) + end if has_column?(:relations) Issue.load_visible_relations(issues) end diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index da89fe2..ba5bdae 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -190,7 +190,7 @@ tr.project.idnt-8 td.name {padding-left: 11em;} tr.project.idnt-9 td.name {padding-left: 12.5em;} tr.issue { text-align: center; white-space: nowrap; } -tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.list, tr.issue td.relations, tr.issue td.parent { white-space: normal; } +tr.issue td.subject, tr.issue td.category, td.assigned_to, td.last_updated_by, tr.issue td.string, tr.issue td.text, tr.issue td.list, tr.issue td.relations, tr.issue td.parent { white-space: normal; } tr.issue td.relations { text-align: left; } tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} tr.issue td.relations span {white-space: nowrap;} diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 097c09d..516069e 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -1117,6 +1117,21 @@ class QueryTest < ActiveSupport::TestCase assert_not_nil issues.first.instance_variable_get("@spent_hours") end + def test_query_should_preload_last_updated_by + q = IssueQuery.new(:name => '_', :column_names => [:subject, :last_updated_by]) + assert q.has_column?(:last_updated_by) + issues = q.issues + assert_not_nil issues.first.instance_variable_get("@last_updated_by") + end + + def test_query_with_last_updated_by_column + q = IssueQuery.new(:name => '_', :column_names => [:subject, :last_updated_by]) + q.filters = {"project_id" => {:operator => '=', :values => [1]}} + + assert_equal ["User", "User", "User", "NilClass", "NilClass", "NilClass", "NilClass"], q.issues.map { |i| i.last_updated_by.class.name} + assert_equal ["John Smith", "John Smith", "Dave Lopper", "", "", "", ""], q.issues.map { |i| i.last_updated_by.to_s } + end + def test_groupable_columns_should_include_custom_fields q = IssueQuery.new column = q.groupable_columns.detect {|c| c.name == :cf_1}