problem.rb
3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Represents a single Problem. The problem may have been
# reported as various Errs, but the user has grouped the
# Errs together as belonging to the same problem.
class Problem
include Mongoid::Document
include Mongoid::Timestamps
field :last_notice_at, :type => DateTime
field :last_deploy_at, :type => Time
field :resolved, :type => Boolean, :default => false
field :issue_link, :type => String
# Cached fields
field :app_name, :type => String
field :notices_count, :type => Integer, :default => 0
field :message
field :environment
field :klass
field :where
index :app_id
index :app_name
index :message
index :last_notice_at
index :last_deploy_at
index :notices_count
belongs_to :app
has_many :errs, :inverse_of => :problem, :dependent => :destroy
has_many :comments, :inverse_of => :err, :dependent => :destroy
scope :resolved, where(:resolved => true)
scope :unresolved, where(:resolved => false)
scope :ordered, order_by(:last_notice_at.desc)
scope :for_apps, lambda {|apps| where(:app_id.in => apps.all.map(&:id))}
before_create :cache_app_attributes
def self.in_env(env)
env.present? ? where(:environment => env) : scoped
end
def notices
Notice.for_errs(errs).ordered
end
def resolve!
self.update_attributes!(:resolved => true)
end
def unresolve!
self.update_attributes!(:resolved => false)
end
def unresolved?
!resolved?
end
def self.merge!(*problems)
problems = problems.flatten.uniq
merged_problem = problems.shift
problems.each do |problem|
merged_problem.errs.concat Err.where(:problem_id => problem.id)
problem.errs(true) # reload problem.errs (should be empty) before problem.destroy
problem.destroy
end
merged_problem.reset_cached_attributes
merged_problem
end
def self.ordered_by(sort, order)
case sort
when "app"; order_by(["app_name", order])
when "message"; order_by(["message", order])
when "last_notice_at"; order_by(["last_notice_at", order])
when "last_deploy_at"; order_by(["last_deploy_at", order])
when "count"; order_by(["notices_count", order])
else raise("\"#{sort}\" is not a recognized sort")
end
end
def merged?
errs.length > 1
end
def unmerge!
[self] + errs[1..-1].map(&:id).map do |err_id|
err = Err.find(err_id)
app.problems.create.tap do |new_problem|
err.update_attribute(:problem_id, new_problem.id)
new_problem.reset_cached_attributes
end
end
end
def reset_cached_attributes
update_attribute(:notices_count, notices.count)
cache_app_attributes
cache_notice_attributes
end
def cache_app_attributes
if app
self.app_name = app.name
self.last_deploy_at = app.last_deploy_at
self.save if persisted?
end
end
def cache_notice_attributes(notice=nil)
notice ||= notices.first
attrs = {:last_notice_at => notices.max(:created_at)}
attrs.merge!(
:message => notice.message,
:environment => notice.environment_name,
:klass => notice.klass,
:where => notice.where) if notice
update_attributes!(attrs)
end
end