Commit fed22b92dd594209d4d4217bd4b5e90408d23de9

Authored by Jared Pace
1 parent 0c314215
Exists in master and in 1 other branch production

Allow users to watch projects and have projects through those watchers

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
1 1 require 'spec_helper'
2 2  
3   -describe AppsController, :focused => true do
  3 +describe AppsController do
4 4  
5 5 it_requires_authentication
6 6 it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete}
... ...
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
... ...