Commit 4e9c6334e8a7ac23bd86fa2b62d4456119a47764

Authored by Pavel Forkert
2 parents a3fb360c ab3e8bb9
Exists in master and in 1 other branch production

Merge branch 'master' of http://github.com/jdpace/errbit

@@ -12,6 +12,7 @@ gem 'mongoid_rails_migrations' @@ -12,6 +12,7 @@ gem 'mongoid_rails_migrations'
12 gem 'useragent', '~> 0.3.1' 12 gem 'useragent', '~> 0.3.1'
13 gem 'pivotal-tracker' 13 gem 'pivotal-tracker'
14 gem 'ruby-fogbugz', :require => 'fogbugz' 14 gem 'ruby-fogbugz', :require => 'fogbugz'
  15 +gem 'inherited_resources'
15 16
16 platform :ruby do 17 platform :ruby do
17 gem 'bson_ext', '~> 1.3.1' 18 gem 'bson_ext', '~> 1.3.1'
@@ -61,7 +61,11 @@ GEM @@ -61,7 +61,11 @@ GEM
61 haml (3.0.25) 61 haml (3.0.25)
62 happymapper (0.3.2) 62 happymapper (0.3.2)
63 libxml-ruby (~> 1.1.3) 63 libxml-ruby (~> 1.1.3)
  64 + has_scope (0.5.1)
64 i18n (0.5.0) 65 i18n (0.5.0)
  66 + inherited_resources (1.2.2)
  67 + has_scope (~> 0.5.0)
  68 + responders (~> 0.6.0)
65 libxml-ruby (1.1.4) 69 libxml-ruby (1.1.4)
66 lighthouse-api (2.0) 70 lighthouse-api (2.0)
67 activeresource (>= 3.0.0) 71 activeresource (>= 3.0.0)
@@ -110,6 +114,7 @@ GEM @@ -110,6 +114,7 @@ GEM
110 rake (>= 0.8.7) 114 rake (>= 0.8.7)
111 thor (~> 0.14.4) 115 thor (~> 0.14.4)
112 rake (0.8.7) 116 rake (0.8.7)
  117 + responders (0.6.4)
113 rest-client (1.5.1) 118 rest-client (1.5.1)
114 mime-types (>= 1.16) 119 mime-types (>= 1.16)
115 rspec (2.5.0) 120 rspec (2.5.0)
@@ -157,6 +162,7 @@ DEPENDENCIES @@ -157,6 +162,7 @@ DEPENDENCIES
157 email_spec 162 email_spec
158 factory_girl_rails 163 factory_girl_rails
159 haml 164 haml
  165 + inherited_resources
160 lighthouse-api 166 lighthouse-api
161 mongoid (= 2.0.2) 167 mongoid (= 2.0.2)
162 mongoid_rails_migrations 168 mongoid_rails_migrations
app/controllers/apps_controller.rb
1 -class AppsController < ApplicationController 1 +class AppsController < InheritedResources::Base
2 2
3 before_filter :require_admin!, :except => [:index, :show] 3 before_filter :require_admin!, :except => [:index, :show]
4 - before_filter :find_app, :except => [:index, :new, :create]  
5 before_filter :parse_email_at_notices_or_set_default, :only => [:create, :update] 4 before_filter :parse_email_at_notices_or_set_default, :only => [:create, :update]
6 5
7 - def index  
8 - @apps = current_user.admin? ? App.all : current_user.apps.all  
9 - end  
10 -  
11 def show 6 def show
12 where_clause = {} 7 where_clause = {}
13 respond_to do |format| 8 respond_to do |format|
14 format.html do 9 format.html do
15 where_clause[:environment] = params[:environment] if(params[:environment].present?) 10 where_clause[:environment] = params[:environment] if(params[:environment].present?)
16 if(params[:all_errs]) 11 if(params[:all_errs])
17 - @errs = @app.errs.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page) 12 + @errs = resource.errs.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page)
18 @all_errs = true 13 @all_errs = true
19 else 14 else
20 - @errs = @app.errs.unresolved.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page) 15 + @errs = resource.errs.unresolved.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page)
21 @all_errs = false 16 @all_errs = false
22 end 17 end
23 @deploys = @app.deploys.order_by(:created_at.desc).limit(5) 18 @deploys = @app.deploys.order_by(:created_at.desc).limit(5)
24 end 19 end
25 format.atom do 20 format.atom do
26 - @errs = @app.errs.unresolved.ordered 21 + @errs = resource.errs.unresolved.ordered
27 end 22 end
28 end 23 end
29 end 24 end
30 25
31 def new 26 def new
32 - @app = App.new  
33 - @app.watchers.build 27 + build_resource.watchers.build
34 @app.issue_tracker = IssueTracker.new 28 @app.issue_tracker = IssueTracker.new
  29 + new!
35 end 30 end
36 31
37 def edit 32 def edit
38 - @app.watchers.build if @app.watchers.none?  
39 - @app.issue_tracker = IssueTracker.new if @app.issue_tracker.nil? 33 + resource.watchers.build if resource.watchers.none?
  34 + resource.issue_tracker = IssueTracker.new if resource.issue_tracker.nil?
  35 + edit!
40 end 36 end
41 37
42 def create 38 def create
43 - @app = App.new(params[:app])  
44 -  
45 - if @app.save  
46 - flash[:success] = 'Great success! Configure your app with the API key below'  
47 - redirect_to app_path(@app)  
48 - else  
49 - render :new  
50 - end 39 + create! :success => 'Great success! Configure your app with the API key below'
51 end 40 end
52 41
53 def update 42 def update
54 - if @app.update_attributes(params[:app])  
55 - flash[:success] = "Good news everyone! '#{@app.name}' was successfully updated."  
56 - redirect_to app_path(@app)  
57 - else  
58 - render :edit  
59 - end 43 + update! :success => "Good news everyone! '#{resource.name}' was successfully updated."
60 end 44 end
61 45
62 def destroy 46 def destroy
63 - @app.destroy  
64 - flash[:success] = "'#{@app.name}' was successfully destroyed."  
65 - redirect_to apps_path 47 + destroy! :success => "'#{resource.name}' was successfully destroyed."
66 end 48 end
67 49
68 protected 50 protected
69 -  
70 - def find_app  
71 - @app = App.find(params[:id])  
72 -  
73 - # Mongoid Bug: could not chain: current_user.apps.find_by_id!  
74 - # apparently finding by 'watchers.email' and 'id' is broken  
75 - raise(Mongoid::Errors::DocumentNotFound.new(App,@app.id)) unless current_user.admin? || current_user.watching?(@app) 51 + def begin_of_association_chain
  52 + current_user unless current_user.admin?
76 end 53 end
77 54
78 # email_at_notices is edited as a string, and stored as an array. 55 # email_at_notices is edited as a string, and stored as an array.
app/models/app.rb
@@ -39,9 +39,8 @@ class App @@ -39,9 +39,8 @@ class App
39 accepts_nested_attributes_for :issue_tracker, :allow_destroy => true, 39 accepts_nested_attributes_for :issue_tracker, :allow_destroy => true,
40 :reject_if => proc { |attrs| !%w(none lighthouseapp redmine pivotal fogbugz mingle).include?(attrs[:issue_tracker_type]) } 40 :reject_if => proc { |attrs| !%w(none lighthouseapp redmine pivotal fogbugz mingle).include?(attrs[:issue_tracker_type]) }
41 41
42 - # Mongoid Bug: find(id) on association proxies returns an Enumerator  
43 def self.find_by_id!(app_id) 42 def self.find_by_id!(app_id)
44 - where(:_id => app_id).first || raise(Mongoid::Errors::DocumentNotFound.new(self,app_id)) 43 + find app_id
45 end 44 end
46 45
47 def self.find_by_api_key!(key) 46 def self.find_by_api_key!(key)
app/models/user.rb
@@ -19,28 +19,21 @@ class User @@ -19,28 +19,21 @@ class User
19 19
20 attr_protected :admin 20 attr_protected :admin
21 21
  22 + has_many :apps, :foreign_key => 'watchers.user_id'
  23 +
22 if Errbit::Config.user_has_username 24 if Errbit::Config.user_has_username
23 field :username 25 field :username
24 validates_presence_of :username 26 validates_presence_of :username
25 end 27 end
26 28
27 - # Mongoid doesn't seem to currently support  
28 - # referencing embedded documents  
29 def watchers 29 def watchers
30 - App.all.map(&:watchers).flatten.select {|w| w.user_id.to_s == id.to_s} 30 + apps.map(&:watchers).flatten.select {|w| w.user_id.to_s == id.to_s}
31 end 31 end
32 32
33 def per_page 33 def per_page
34 self[:per_page] || PER_PAGE 34 self[:per_page] || PER_PAGE
35 end 35 end
36 36
37 - def apps  
38 - # This is completely wasteful but became necessary  
39 - # due to bugs in Mongoid  
40 - app_ids = watchers.map {|w| w.app.id}  
41 - App.any_in(:_id => app_ids)  
42 - end  
43 -  
44 def watching?(app) 37 def watching?(app)
45 apps.all.include?(app) 38 apps.all.include?(app)
46 end 39 end
app/models/watcher.rb
@@ -5,7 +5,7 @@ class Watcher @@ -5,7 +5,7 @@ class Watcher
5 field :email 5 field :email
6 6
7 embedded_in :app, :inverse_of => :watchers 7 embedded_in :app, :inverse_of => :watchers
8 - referenced_in :user 8 + belongs_to :user
9 9
10 validate :ensure_user_or_email 10 validate :ensure_user_or_email
11 11
app/views/errs/redmine_body.txt.erb
1 -"See this exception on Errbit":<%= app_err_url err.app, err %>  
2 <% if notice = err.notices.first %> 1 <% if notice = err.notices.first %>
3 h1. <%= notice.message %> 2 h1. <%= notice.message %>
4 3
  4 +h3. "See this exception on Errbit":<%= app_err_url err.app, err %>
  5 +
5 h2. Summary 6 h2. Summary
6 <% if notice.request['url'].present? %> 7 <% if notice.request['url'].present? %>
7 h3. URL 8 h3. URL
@@ -30,16 +31,14 @@ h2. Session @@ -30,16 +31,14 @@ h2. Session
30 31
31 h2. Backtrace 32 h2. Backtrace
32 33
33 -<pre>  
34 -<% for line in notice.backtrace %><%= line['number'] %>: <%= line['file'].sub(/^\[PROJECT_ROOT\]/, '') %> -> *<%= line['method'] %>* 34 +| Line | File | Method |
  35 +<% for line in notice.backtrace %>| <%= line['number'] %> | <%= line['file'].sub(/^\[PROJECT_ROOT\]/, '') %> | *<%= line['method'] %>* |
35 <% end %> 36 <% end %>
36 -</pre>  
37 37
38 h2. Environment 38 h2. Environment
39 39
40 -<pre>  
41 -<% for key, val in notice.env_vars %>  
42 -<%= key %>: <%= val %> 40 +<% for key, val in notice.env_vars %>| <%= key %> | <%= val %> |
43 <% end %> 41 <% end %>
44 -</pre> 42 +
45 <% end %> 43 <% end %>
  44 +
spec/controllers/apps_controller_spec.rb
@@ -201,15 +201,7 @@ describe AppsController do @@ -201,15 +201,7 @@ describe AppsController do
201 201
202 it "should display a message" do 202 it "should display a message" do
203 post :create, :app => {} 203 post :create, :app => {}
204 - request.flash[:success].should match(/success/)  
205 - end  
206 - end  
207 -  
208 - context "when the create is unsuccessful" do  
209 - it "should render the new page" do  
210 - @app.should_receive(:save).and_return(false)  
211 - post :create, :app => {}  
212 - response.should render_template(:new) 204 + request.flash[:notice].should match(/success/)
213 end 205 end
214 end 206 end
215 end 207 end
@@ -227,7 +219,7 @@ describe AppsController do @@ -227,7 +219,7 @@ describe AppsController do
227 219
228 it "should display a message" do 220 it "should display a message" do
229 put :update, :id => @app.id, :app => {} 221 put :update, :id => @app.id, :app => {}
230 - request.flash[:success].should match(/success/) 222 + request.flash[:notice].should match(/success/)
231 end 223 end
232 end 224 end
233 225
@@ -432,7 +424,7 @@ describe AppsController do @@ -432,7 +424,7 @@ describe AppsController do
432 424
433 it "should display a message" do 425 it "should display a message" do
434 delete :destroy, :id => @app.id 426 delete :destroy, :id => @app.id
435 - request.flash[:success].should match(/success/) 427 + request.flash[:notice].should match(/success/)
436 end 428 end
437 429
438 it "should redirect to the apps page" do 430 it "should redirect to the apps page" do