has_many :watchers, :as => :watchable, :dependent => :delete_all
has_many :watcher_users, :through => :watchers, :source => :user, :validate => false
- scope :watched_by, lambda { |user_id|
+ scope :watched_by, lambda { |principal|
+ user_ids = Array(principal.id)
+ user_ids |= principal.group_ids if principal.is_a?(User)
+ user_ids.compact!
+
joins(:watchers).
- where("#{Watcher.table_name}.user_id = ?", user_id)
+ where("#{Watcher.table_name}.user_id IN (?)", user_ids)
}
end
send :include, Redmine::Acts::Watchable::InstanceMethods
super user_ids
end
- # Returns true if object is watched by +user+
- def watched_by?(user)
- !!(user && self.watcher_user_ids.detect {|uid| uid == user.id })
+ # Returns true if object is watched by +principal+, that is
+ # either by a given group,
+ # or by a given user or any of their groups
+ def watched_by?(principal)
+ return false unless principal
+
+ user_ids = Array(principal.id)
+ user_ids |= principal.group_ids if principal.is_a?(User)
+ user_ids.compact!
+
+ (self.watcher_user_ids & user_ids).any?
end
def notified_watchers
require File.expand_path('../../test_helper', __FILE__)
class WatcherTest < ActiveSupport::TestCase
- fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules,
+ fixtures :projects, :groups_users, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules,
:issues, :issue_statuses, :enumerations, :trackers, :projects_trackers,
:boards, :messages,
:wikis, :wiki_pages,
assert Issue.watched_by(@user).include?(@issue)
end
+ def test_watched_by_group
+ group = Group.find(10)
+ user = User.find(8)
+ assert @issue.add_watcher(group)
+ @issue.reload
+
+ assert @issue.watched_by?(group)
+ assert Issue.watched_by(group).include?(@issue)
+
+ assert @issue.watched_by?(user)
+ assert Issue.watched_by(user).include?(@issue)
+ end
+
def test_watcher_users
watcher_users = Issue.find(2).watcher_users
assert_kind_of Array, watcher_users.collect{|w| w}