From 22c1e2b8cf8527c1e97de976f3dd46e7bee7cba3 Mon Sep 17 00:00:00 2001
From: Eric Davis <edavis@littlestreamsoftware.com>
Date: Wed, 10 Mar 2010 05:10:43 +0000
Subject: [PATCH] Adds named scopes to replace custom finders.

* Adds watched_by class method in ActsAsWatchable
* Adds Issue#recently_updated, Issue#with_limit and Issue#on_active_project

  #2482

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3557 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
 app/models/issue.rb                           |  8 +++++++-
 app/views/my/blocks/_issueswatched.rhtml      |  9 ++-------
 test/unit/issue_test.rb                       | 20 +++++++++++++++++++
 .../lib/acts_as_watchable.rb                  | 13 +++++-------
 4 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/app/models/issue.rb b/app/models/issue.rb
index 9aaebce73..ffce8ea18 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -49,8 +49,9 @@ class Issue < ActiveRecord::Base
   DONE_RATIO_OPTIONS = %w(issue_field issue_status)
 
   attr_reader :current_journal
-  
+
   validates_presence_of :subject, :priority, :project, :tracker, :author, :status
+
   validates_length_of :subject, :maximum => 255
   validates_inclusion_of :done_ratio, :in => 0..100
   validates_numericality_of :estimated_hours, :allow_nil => true
@@ -60,6 +61,11 @@ class Issue < ActiveRecord::Base
   
   named_scope :open, :conditions => ["#{IssueStatus.table_name}.is_closed = ?", false], :include => :status
 
+  named_scope :recently_updated, :order => "#{self.table_name}.updated_on DESC"
+  named_scope :with_limit, lambda { |limit| { :limit => limit} }
+  named_scope :on_active_project, :include => [:status, :project, :tracker],
+                                  :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
+
   before_create :default_assign
   before_save :reschedule_following_issues, :close_duplicates, :update_done_ratio_from_issue_status
   after_save :create_journal
diff --git a/app/views/my/blocks/_issueswatched.rhtml b/app/views/my/blocks/_issueswatched.rhtml
index 04f326c25..e48ec1662 100644
--- a/app/views/my/blocks/_issueswatched.rhtml
+++ b/app/views/my/blocks/_issueswatched.rhtml
@@ -1,10 +1,5 @@
-<h3><%=l(:label_watched_issues)%> (<%= Issue.visible.count(:include => :watchers,
-												 																	 :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]) %>)</h3>
-<% watched_issues = Issue.visible.find(:all, 
-                               :include => [:status, :project, :tracker, :watchers],
-                               :limit => 10, 
-                               :conditions => ["#{Watcher.table_name}.user_id = ?", user.id],
-                               :order => "#{Issue.table_name}.updated_on DESC") %>
+<h3><%=l(:label_watched_issues)%> (<%= Issue.visible.watched_by(user.id).count %>)</h3>
+<% watched_issues = Issue.visible.on_active_project.watched_by(user.id).recently_updated.with_limit(10) %>
 
 <%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %>
 <% if watched_issues.length > 0 %>
diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb
index 24442b5d4..f0db47a31 100644
--- a/test/unit/issue_test.rb
+++ b/test/unit/issue_test.rb
@@ -656,4 +656,24 @@ class IssueTest < ActiveSupport::TestCase
     assert_equal 2, groups.size
     assert_equal 5, groups.inject(0) {|sum, group| sum + group['total'].to_i}
   end
+
+  def test_recently_updated_with_limit_scopes
+    #should return the last updated issue
+    assert_equal 1, Issue.recently_updated.with_limit(1).length
+    assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
+  end
+
+  def test_on_active_projects_scope
+    assert Project.find(2).archive
+    
+    before = Issue.on_active_project.length
+    # test inclusion to results
+    issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
+    assert_equal before + 1, Issue.on_active_project.length
+
+    # Move to an archived project
+    issue.project = Project.find(2)
+    assert issue.save
+    assert_equal before, Issue.on_active_project.length
+  end
 end
diff --git a/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb
index c13da4fd4..f99f4a60d 100644
--- a/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb
+++ b/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb
@@ -15,6 +15,10 @@ module Redmine
             has_many :watchers, :as => :watchable, :dependent => :delete_all
             has_many :watcher_users, :through => :watchers, :source => :user
             
+            named_scope :watched_by, lambda { |user_id|
+              { :include => :watchers,
+                :conditions => ["#{Watcher.table_name}.user_id = ?", user_id] }
+            }
             attr_protected :watcher_ids, :watcher_user_ids
           end
         end
@@ -60,14 +64,7 @@ module Redmine
           notified.collect(&:mail).compact
         end
 
-        module ClassMethods
-          # Returns the objects that are watched by user
-          def watched_by(user)
-            find(:all, 
-                 :include => :watchers,
-                 :conditions => ["#{Watcher.table_name}.user_id = ?", user.id])
-          end
-        end
+        module ClassMethods; end
       end
     end
   end
-- 
GitLab