Class: Measurement

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/measurement.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.debug(colored: true) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/models/measurement.rb', line 88

def debug(colored: true)
  format_subject = ->(s) { s.is_a?(User) ? s.first_name : s.is_a?(Project) ? s.slug : "" }
  includes(:subject).reorder("taken_at ASC, subject_type ASC, subject_id ASC, name ASC").map { |m|
    line = [ m.taken_on.strftime("%-m/%-d").rjust(5),
             m.taken_at.strftime("%H:%M:%S"),
             format_subject[m.subject].ljust(9),
             m.name.ljust(50),
             m.value.rjust(8) ].join(" ")
    line = "\e[36m#{line}\e[0m" if colored && m.subject_type == "User"
    line = "\e[35m#{line}\e[0m" if colored && m.subject_type == "Project"
    line }.join("\n")
end

.for(subject) ⇒ Object



50
51
52
53
54
# File 'app/models/measurement.rb', line 50

def for(subject)
  return where(subject_type: nil, subject_id: nil) if subject.nil?
  return where(subject_type: subject.name) if subject.is_a?(Class)
  where(subject_type: subject.class.name, subject_id: subject.id)
end

.globalObject



56
57
58
# File 'app/models/measurement.rb', line 56

def global
  self.for(nil)
end

.meanObject



82
83
84
85
86
# File 'app/models/measurement.rb', line 82

def mean
  denominator = count
  return nil if denominator.zero?
  total.to_f / denominator
end

.named(*name_patterns) ⇒ Object

Valid identifies for names

- weekly.hours.charged
- weekly.hours.charged.*
- weekly.hours.charged.{fix,chore}
- weekly.hours.{worked,charged}.fix

Invalid arguments

- weekly.hours.*.fix


67
68
69
70
71
72
# File 'app/models/measurement.rb', line 67

def named(*name_patterns)
  name_patterns =  name_patterns.flatten.map { |pattern| pattern
    .gsub(/\{([\w\-,]+)\}/) { "(#{$~.captures[0].gsub(/,/, "|")})" }
    .gsub(/\*$/, "%") }
  where(["name SIMILAR TO ?", "(#{name_patterns.join("|")})"])
end

.take!(attributes) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'app/models/measurement.rb', line 11

def take!(attributes)
  required_keys = [:subject_type, :subject_id, :taken_at, :name].freeze

  identifying_attributes = attributes.pick(required_keys)
  subject = attributes[:subject]
  identifying_attributes.merge!(subject_type: subject.class.name, subject_id: subject.id) if subject
  identifying_attributes.reverse_merge!(subject_type: nil, subject_id: nil)

  required_keys.each do |key|
    raise ArgumentError, "#{key.inspect} is required to take a measurement" unless identifying_attributes.key?(key)
  end

  find_or_initialize_by(identifying_attributes).tap do |measurement|
    measurement.value = attributes[:value]
    measurement.save!
  end
end

.taken_after(date) ⇒ Object Also known as: taken_since



41
42
43
# File 'app/models/measurement.rb', line 41

def taken_after(date)
  where(arel_table[:taken_on].gteq(date))
end

.taken_at(time) ⇒ Object



29
30
31
# File 'app/models/measurement.rb', line 29

def taken_at(time)
  where(taken_at: time)
end

.taken_before(date) ⇒ Object



37
38
39
# File 'app/models/measurement.rb', line 37

def taken_before(date)
  where(arel_table[:taken_on].lteq(date))
end

.taken_between(date0, date1) ⇒ Object



46
47
48
# File 'app/models/measurement.rb', line 46

def taken_between(date0, date1)
  taken_after(date0).taken_before(date1)
end

.taken_on(date) ⇒ Object



33
34
35
# File 'app/models/measurement.rb', line 33

def taken_on(date)
  where(taken_on: date)
end

.totalObject



74
75
76
# File 'app/models/measurement.rb', line 74

def total
  pluck(:value).inject(0) { |sum, value| sum + value.to_d }
end

.valueObject



78
79
80
# File 'app/models/measurement.rb', line 78

def value
  limit(1).pluck(:value)[0]
end

Instance Method Details

#taken_at=(value) ⇒ Object



102
103
104
105
# File 'app/models/measurement.rb', line 102

def taken_at=(value)
  super
  self.taken_on = value && value.to_date
end

#taken_on?(date) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
# File 'app/models/measurement.rb', line 107

def taken_on?(date)
  taken_on == date
end