mongoid-historicals 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,5 +1,40 @@
1
1
  Mongoid Historicals
2
2
  ===================
3
3
 
4
- Record a snapshot of current values to reference later as historical values. Useful for showing changes in values over time.
4
+ Record a snapshot of current values to reference later as historical values.
5
+
6
+
7
+ Installation
8
+ ------------
9
+
10
+ Add to your Gemfile
11
+
12
+ gem 'mongoid-historicals', :require => 'mongoid/historicals'
13
+
14
+
15
+ Usage
16
+ -----
17
+
18
+ Here is an example of how to track the week-to-week score for the players in my fictional MMORPGFPS:
19
+
20
+ class Player
21
+ include Mongoid::Document
22
+ include Mongoid::Historicals
23
+
24
+ field :username, type: String
25
+ field :score, type: Integer
26
+
27
+ historicals :score, :max => 52, :frequency => :weekly
28
+ end
29
+
30
+ In a cron task, I could run the following every Sunday before midnight:
31
+
32
+ Player.all.each do |player|
33
+ player.record!
34
+ end
35
+
36
+ Then, I could show each player's historical score like this:
37
+
38
+ <h2>Your Current Score: <%= @player.score %></h2>
39
+ <p>Your Score Last Week: <%= @player.historical(:score, 1.week.ago) %> / Difference: <%= @player.historical_difference(:score, 1.week.ago) %></p>
5
40
 
@@ -1,7 +1,7 @@
1
1
  module Mongoid
2
2
  module Historicals
3
3
 
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
 
6
6
  end
7
7
  end
@@ -14,8 +14,11 @@ module Mongoid
14
14
  class_attribute :historical_options
15
15
  end
16
16
 
17
- # Save the current values for historicals by label
17
+ # Save the current values as a historical record
18
18
  #
19
+ # @param [String, #to_datetime] label The label as a String, Symbol or DateTime that the historical record will be saved as. If you pass a DateTime object, it
20
+ # will use the <tt>:frequency</tt> option from historicals to save as a date/time.
21
+ # @return [Record] the historical record that is saved
19
22
  def record!(label = nil)
20
23
  label ||= Time.now
21
24
  record = historical(label) || self.historicals.build(:'_label' => labelize(label))
@@ -29,24 +32,72 @@ module Mongoid
29
32
  record
30
33
  end
31
34
 
32
- def historical(label)
33
- self.historicals.where(:'_label' => labelize(label)).first
35
+ # Retrieve the historical record or a single attribute value from the
36
+ # specified label. If only one argument is given, it will return
37
+ # the entire record with that label. If two arguments are given, the
38
+ # first argument will specify the attribute and the second argument is the
39
+ # label to use.
40
+ #
41
+ # @param [String, #to_datetime] attr_or_label If only one argument is given,
42
+ # this is the <tt>label</tt> for the record to be returned. If two arguments
43
+ # are given, this should be the symbol of the attribute whose value should
44
+ # be returned.
45
+ # @return With one argument given, the historical record or nil if none
46
+ # exists. With two arguments given, it should return the value of the
47
+ # requested attribute for the specified label.
48
+ def historical(attr_or_label, label = nil)
49
+ if label.nil?
50
+ self.historicals.where(:'_label' => labelize(attr_or_label)).first
51
+ else
52
+ record = self.historicals.where(:'_label' => labelize(label)).first
53
+
54
+ if record
55
+ record[attr_or_label]
56
+ else
57
+ nil
58
+ end
59
+ end
34
60
  end
35
61
 
62
+ # Return the difference between the current value of the attribute and the value of attribute from the
63
+ # <tt>label</tt> historical record.
64
+ #
65
+ # @param [Symbol] attr The attribute on which you are calculating the difference
66
+ # @param [String, Symbol, #to_datetime] label The label as a String, Symbol or Datetime for the historical record against which you are comparing
67
+ # @param [Hash] options
68
+ # @option options [Object] :default The value you want returned if there is no historical for comparison (default: 0)
36
69
  def historical_difference(attr, label, options = {})
37
70
  opts = {
38
71
  default: 0
39
72
  }.merge(options)
40
73
 
41
- record = historical(labelize(label))
42
-
43
74
  begin
44
- self[attr] - record[attr]
75
+ self[attr] - historical(attr, label)
45
76
  rescue # Pokemon exception handling, but actually seems appropriate here
46
77
  opts[:default]
47
78
  end
48
79
  end
49
80
 
81
+ module ClassMethods
82
+
83
+ # This model should record historical values for the specified
84
+ # attributes.
85
+ #
86
+ # @overload historicals(*attrs, options = {})
87
+ # @param [Array] attrs The symbol(s) for the attributes for which you want to store historicals
88
+ # @param [Hash] options
89
+ # @option options [Integer] :max The maximum number of entries to store (default: unlimited)
90
+ # @option options [:monthly,:weekly,:daily] :frequency The frequency to use for DateTime labels (default: :daily)
91
+ def historicals(*attrs)
92
+ options = attrs.extract_options!
93
+ options[:max] ||= nil
94
+ options[:frequency] ||= :daily
95
+
96
+ self.historical_options = options
97
+ self.historical_attributes = attrs
98
+ end
99
+ end
100
+
50
101
  private
51
102
 
52
103
  def labelize(label)
@@ -79,25 +130,5 @@ module Mongoid
79
130
  end
80
131
  end
81
132
  end
82
-
83
- module ClassMethods
84
-
85
- # This model should record historical values for the specified
86
- # attributes.
87
- #
88
- # Options:
89
- #
90
- # <tt>max</tt>: The maximum number of entries to store (default: none)
91
- # <tt>frequency</tt>: :monthly, :weekly, or :daily (default: :daily)
92
- #
93
- def historicals(*attrs)
94
- options = attrs.extract_options!
95
- options[:max] ||= nil
96
- options[:frequency] ||= :daily
97
-
98
- self.historical_options = options
99
- self.historical_attributes = attrs
100
- end
101
- end
102
133
  end
103
134
  end
@@ -95,18 +95,38 @@ describe Mongoid::Historicals do
95
95
  @player.record!('test')
96
96
  end
97
97
 
98
- describe "when record exists" do
99
- it "should return record" do
100
- @record = @player.historical('test')
101
- @record.must_be_instance_of(Mongoid::Historicals::Record)
102
- @record._label.must_equal 'test'
98
+ describe "with one argument" do
99
+ describe "when record exists" do
100
+ it "should return record with specified label" do
101
+ @record = @player.historical('test')
102
+ @record.must_be_instance_of(Mongoid::Historicals::Record)
103
+ @record._label.must_equal 'test'
104
+ end
105
+ end
106
+
107
+ describe "when record does not exist" do
108
+ it "should return nil" do
109
+ @record = @player.historical('unknown-label')
110
+ @record.must_equal nil
111
+ end
103
112
  end
104
113
  end
105
114
 
106
- describe "when record does not exist" do
107
- it "should return nil" do
108
- @record = @player.historical('unknown-label')
109
- @record.must_equal nil
115
+ describe "with two arguments" do
116
+ it "should return historical value (from label) of specified attribute" do
117
+ @player.historical(:score, 'test').must_equal 95.0
118
+ end
119
+
120
+ describe "when record does not exist" do
121
+ it "should return nil" do
122
+ @player.historical(:score, 'invalid').must_equal nil
123
+ end
124
+ end
125
+
126
+ describe "when attribute does not exist" do
127
+ it "should return nil" do
128
+ @player.historical(:invalid, 'test').must_equal nil
129
+ end
110
130
  end
111
131
  end
112
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-historicals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -99,3 +99,4 @@ signing_key:
99
99
  specification_version: 3
100
100
  summary: ''
101
101
  test_files: []
102
+ has_rdoc: