Commit d6f2faeb0a3891181fbcade42dc1ec5f3f656f39

Authored by Robert Lail
Committed by Nathan Broadbent
1 parent e4c691d2
Exists in master and in 1 other branch production

validate Problem#last_notice_at; ensure that it isn't nil

resolves the apparent sorting fail on problems by last notice timestamp
app/helpers/errs_helper.rb
1 1 module ErrsHelper
2   - def last_notice_at(problem)
3   - problem.last_notice_at || problem.created_at
4   - end
5   -
6 2 def err_confirm
7 3 Errbit::Config.confirm_resolve_err === false ? nil : 'Seriously?'
8 4 end
... ...
app/models/problem.rb
... ... @@ -6,8 +6,8 @@ class Problem
6 6 include Mongoid::Document
7 7 include Mongoid::Timestamps
8 8  
9   - field :last_notice_at, :type => DateTime
10   - field :first_notice_at, :type => DateTime
  9 + field :last_notice_at, :type => DateTime, :default => Proc.new { Time.now }
  10 + field :first_notice_at, :type => DateTime, :default => Proc.new { Time.now }
11 11 field :last_deploy_at, :type => Time
12 12 field :resolved, :type => Boolean, :default => false
13 13 field :resolved_at, :type => Time
... ... @@ -45,6 +45,8 @@ class Problem
45 45 scope :unresolved, where(:resolved => false)
46 46 scope :ordered, order_by(:last_notice_at.desc)
47 47 scope :for_apps, lambda {|apps| where(:app_id.in => apps.all.map(&:id))}
  48 +
  49 + validates_presence_of :last_notice_at, :first_notice_at
48 50  
49 51  
50 52 def self.in_env(env)
... ... @@ -132,17 +134,22 @@ class Problem
132 134 end
133 135  
134 136 def cache_notice_attributes(notice=nil)
135   - notice ||= notices.first
136   - attrs = {:last_notice_at => notices.order_by([:created_at, :asc]).last.try(:created_at), :first_notice_at => notices.order_by([:created_at, :asc]).first.try(:created_at)}
  137 + first_notice = notices.order_by([:created_at, :asc]).first
  138 + last_notice = notices.order_by([:created_at, :asc]).last
  139 + notice ||= first_notice
  140 +
  141 + attrs = {}
  142 + attrs[:first_notice_at] = first_notice.created_at if first_notice
  143 + attrs[:last_notice_at] = last_notice.created_at if last_notice
137 144 attrs.merge!(
138   - :message => notice.message,
  145 + :message => notice.message,
139 146 :environment => notice.environment_name,
140 147 :error_class => notice.error_class,
141   - :where => notice.where,
  148 + :where => notice.where,
142 149 :messages => attribute_count_increase(:messages, notice.message),
143 150 :hosts => attribute_count_increase(:hosts, notice.host),
144 151 :user_agents => attribute_count_increase(:user_agents, notice.user_agent_string)
145   - ) if notice
  152 + ) if notice
146 153 update_attributes!(attrs)
147 154 end
148 155  
... ...
app/views/errs/_table.html.haml
... ... @@ -33,7 +33,7 @@
33 33 - if comment.user
34 34 %em.commenter= (Errbit::Config.user_has_username ? comment.user.username : comment.user.email).to_s << ":"
35 35 %em= truncate(comment.body, :length => 100, :separator => ' ')
36   - %td.latest #{time_ago_in_words(last_notice_at problem)} ago
  36 + %td.latest #{time_ago_in_words(problem.last_notice_at)} ago
37 37 %td.deploy= problem.last_deploy_at ? problem.last_deploy_at.to_s(:micro) : 'n/a'
38 38 %td.count= link_to problem.notices_count, app_err_path(problem.app, problem)
39 39 - if any_issue_links
... ...
app/views/errs/show.html.haml
... ... @@ -10,7 +10,7 @@
10 10 %strong Environment:
11 11 = @problem.environment
12 12 %strong Last Notice:
13   - = last_notice_at(@problem).to_s(:precise)
  13 + = @problem.last_notice_at.to_s(:precise)
14 14 - content_for :action_bar do
15 15 - if @problem.unresolved?
16 16 %span= link_to 'resolve', resolve_app_err_path(@app, @problem), :method => :put, :data => { :confirm => err_confirm }, :class => 'resolve'
... ...
db/migrate/20120829034812_ensure_that_problems_last_notice_at_is_not_nil.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +class EnsureThatProblemsLastNoticeAtIsNotNil < Mongoid::Migration
  2 + def self.up
  3 + Problem.where("$or" => [{:last_notice_at => nil}, {:first_notice_at => nil}]).each do |problem|
  4 + first_notice = problem.notices.order_by([:created_at, :asc]).first
  5 +
  6 + # Destroy problems with no notices
  7 + if first_notice.nil?
  8 + problem.destroy
  9 + next
  10 + end
  11 +
  12 + last_notice = problem.notices.order_by([:created_at, :asc]).last
  13 +
  14 + problem.update_attributes!({
  15 + :first_notice_at => first_notice.created_at,
  16 + :last_notice_at => last_notice.created_at
  17 + })
  18 + end
  19 + end
  20 +
  21 + def self.down
  22 + end
  23 +end
... ...
spec/models/problem_spec.rb
... ... @@ -24,14 +24,13 @@ describe Problem do
24 24 end
25 25 end
26 26 end
  27 +
27 28 context '#last_notice_at' do
28 29 it "returns the created_at timestamp of the latest notice" do
29 30 err = Fabricate(:err)
30 31 problem = err.problem
31 32 problem.should_not be_nil
32 33  
33   - problem.last_notice_at.should be_nil
34   -
35 34 notice1 = Fabricate(:notice, :err => err)
36 35 problem.last_notice_at.should == notice1.created_at
37 36  
... ... @@ -46,8 +45,6 @@ describe Problem do
46 45 problem = err.problem
47 46 problem.should_not be_nil
48 47  
49   - problem.first_notice_at.should be_nil
50   -
51 48 notice1 = Fabricate(:notice, :err => err)
52 49 problem.first_notice_at.should == notice1.created_at
53 50  
... ...