Commit fed22b92dd594209d4d4217bd4b5e90408d23de9
1 parent
0c314215
Exists in
master
and in
1 other branch
Allow users to watch projects and have projects through those watchers
Showing
5 changed files
with
70 additions
and
6 deletions
Show diff stats
app/models/user.rb
... | ... | @@ -8,7 +8,24 @@ class User |
8 | 8 | |
9 | 9 | field :name |
10 | 10 | field :admin, :type => Boolean, :default => false |
11 | + | |
12 | + after_destroy :destroy_watchers | |
11 | 13 | |
12 | 14 | validates_presence_of :name |
13 | - | |
15 | + | |
16 | + # Mongoid doesn't seem to currently support | |
17 | + # referencing embedded documents | |
18 | + def watchers | |
19 | + App.all.map(&:watchers).flatten.select {|w| w.user_id == id} | |
20 | + end | |
21 | + | |
22 | + def apps | |
23 | + App.where('watchers.user_id' => id) | |
24 | + end | |
25 | + | |
26 | + protected | |
27 | + | |
28 | + def destroy_watchers | |
29 | + watchers.each(&:destroy) | |
30 | + end | |
14 | 31 | end | ... | ... |
app/models/watcher.rb
... | ... | @@ -5,7 +5,14 @@ class Watcher |
5 | 5 | field :email |
6 | 6 | |
7 | 7 | embedded_in :app, :inverse_of => :watchers |
8 | + referenced_in :user | |
8 | 9 | |
9 | - validates_presence_of :email | |
10 | + validate :ensure_user_or_email | |
11 | + | |
12 | + protected | |
13 | + | |
14 | + def ensure_user_or_email | |
15 | + errors.add(:base, "You must specify either a user or an email address") unless user.present? || email.present? | |
16 | + end | |
10 | 17 | |
11 | 18 | end | ... | ... |
spec/controllers/apps_controller_spec.rb
spec/models/user_spec.rb
... | ... | @@ -10,4 +10,33 @@ describe User do |
10 | 10 | end |
11 | 11 | end |
12 | 12 | |
13 | + context 'Watchers' do | |
14 | + | |
15 | + it 'has many watchers' do | |
16 | + user = Factory(:user) | |
17 | + watcher = Factory(:watcher, :user => user, :email => nil) | |
18 | + user.watchers.should_not be_empty | |
19 | + user.watchers.should include(watcher) | |
20 | + end | |
21 | + | |
22 | + it "destroys any related watchers when it is destroyed" do | |
23 | + user = Factory(:user) | |
24 | + app = Factory(:app) | |
25 | + watcher = Factory(:watcher, :app => app, :user => user, :email => nil) | |
26 | + user.watchers.should_not be_empty | |
27 | + user.destroy | |
28 | + app.reload.watchers.should_not include(watcher) | |
29 | + end | |
30 | + | |
31 | + it "has many apps through watchers" do | |
32 | + user = Factory(:user) | |
33 | + watched_app = Factory(:app) | |
34 | + unwatched_app = Factory(:app) | |
35 | + watcher = Factory(:watcher, :app => watched_app, :user => user, :email => nil) | |
36 | + user.apps.all.should include(watched_app) | |
37 | + user.apps.all.should_not include(unwatched_app) | |
38 | + end | |
39 | + | |
40 | + end | |
41 | + | |
13 | 42 | end | ... | ... |
spec/models/watcher_spec.rb
... | ... | @@ -3,11 +3,22 @@ require 'spec_helper' |
3 | 3 | describe Watcher do |
4 | 4 | |
5 | 5 | context 'validations' do |
6 | - it 'requires an email address' do | |
7 | - watcher = Factory.build(:watcher, :email => nil) | |
6 | + it 'requires an email address or an associated user' do | |
7 | + watcher = Factory.build(:watcher, :email => nil, :user => nil) | |
8 | 8 | watcher.should_not be_valid |
9 | - watcher.errors[:email].should include("can't be blank") | |
9 | + watcher.errors[:base].should include("You must specify either a user or an email address") | |
10 | + | |
11 | + watcher.email = 'watcher@example.com' | |
12 | + watcher.should be_valid | |
13 | + | |
14 | + watcher.email = nil | |
15 | + watcher.should_not be_valid | |
16 | + | |
17 | + watcher.user = Factory(:user) | |
18 | + watcher.should be_valid | |
10 | 19 | end |
20 | + | |
21 | + | |
11 | 22 | end |
12 | 23 | |
13 | 24 | end | ... | ... |