diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index b69837c2a..0d3951203 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -28,7 +28,7 @@ module WatchersHelper return '' unless user && user.logged? objects = Array.wrap(objects) - watched = objects.any? {|object| object.watched_by?(user)} + watched = Watcher.any_watched?(objects, user) css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ') text = watched ? l(:button_unwatch) : l(:button_watch) url = watch_path( diff --git a/app/models/watcher.rb b/app/models/watcher.rb index 1cea711b7..3a37aa323 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -23,6 +23,19 @@ class Watcher < ActiveRecord::Base validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] validate :validate_user + # Returns true if at least one object among objects is watched by user + def self.any_watched?(objects, user) + objects = objects.reject(&:new_record?) + if objects.any? + objects.group_by {|object| object.class.base_class}.each do |base_class, objects| + if Watcher.where(:watchable_type => base_class.name, :watchable_id => objects.map(&:id), :user_id => user.id).exists? + return true + end + end + end + false + end + # Unwatch things that users are no longer allowed to view def self.prune(options={}) if options.has_key?(:user) diff --git a/test/unit/watcher_test.rb b/test/unit/watcher_test.rb index 6719ee8a6..fb1163aae 100644 --- a/test/unit/watcher_test.rb +++ b/test/unit/watcher_test.rb @@ -99,6 +99,23 @@ class WatcherTest < ActiveSupport::TestCase assert_nil issue.addable_watcher_users.detect {|user| !issue.visible?(user)} end + def test_any_watched_should_return_false_if_no_object_is_watched + objects = (0..2).map {Issue.generate!} + + assert_equal false, Watcher.any_watched?(objects, @user) + end + + def test_any_watched_should_return_true_if_one_object_is_watched + objects = (0..2).map {Issue.generate!} + objects.last.add_watcher(@user) + + assert_equal true, Watcher.any_watched?(objects, @user) + end + + def test_any_watched_should_return_false_with_no_object + assert_equal false, Watcher.any_watched?([], @user) + end + def test_recipients @issue.watchers.delete_all @issue.reload