attributes_history 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5ab51f8fcbd9cad95f6e3724546f8f5d57fb848
4
- data.tar.gz: ecdc7309e290238fc6b21bf46c259b76f9dff6bc
3
+ metadata.gz: 047e72c287edac9652bb432b71b3fe4b2e0e7822
4
+ data.tar.gz: fe7bcfe8813faff091440a3f591467c6d6c79dc0
5
5
  SHA512:
6
- metadata.gz: 7c05774dccf3d142db49d91e8a949aa4cb4d80159c9839b36a31f62c5c7b2cc7cc82487d473e9c1ae432d651718fa21a5e38a136c12a1b886041a6ea58f2fd43
7
- data.tar.gz: d054f8a660744d412454a4c086bb881accbeb0cbc39db75115218ffa3a7b64abbb4efb50e5a67d603f8885547d0243fdce8a025450d4433f0fe15f863bc90967
6
+ metadata.gz: 07329646bcc03cfc94c4687339bf3f6296f3ddf85c8ec3c4d11114b72f15eb6c0dc0cd10492e35288c7c3a105b9ed958ec7f7fec9f32faee923376ae19f4133d
7
+ data.tar.gz: e09f2bf36bd530e5894c51f3c4cc575e6fe11e346acc395d00eea6afd08b277ec8af2285e5f77b7f75f233a45145e00348af80adcb4dc965857fb945425471b2
data/README.md CHANGED
@@ -96,6 +96,24 @@ This is similar to how [paper_trail](https://github.com/airblade/paper_trail)
96
96
  works in that the versions represent past data, and only the current regular
97
97
  model record (contact in this case) has the current state.
98
98
 
99
+ ## Multiple `has_attributes_history` calls per class
100
+
101
+ If you want to have some attributes (or groups of attributes) stored in
102
+ different tables grouped by semantic meaning or because their size or rate of
103
+ change is different, you can specify multiple `has_attributes_history` calls per
104
+ class. The lists of attributes for the different calls can't have any
105
+ overlapping attributes though or that will confuse the lookup logic.
106
+
107
+ Here's an example of tracking `notes` in a separate log from `status` and
108
+ `pledge`:
109
+
110
+ ```
111
+ class Contact < ActiveRecord::Base
112
+ has_attributes_history for: [:status, :pledge], with_model: PartnerStatusLog
113
+ has_attributes_history for: [:notes], with_model: ContactNotesLog
114
+ end
115
+ ```
116
+
99
117
  ## Enabling and disabling
100
118
 
101
119
  By default the history logging is enabled once you set it up, but you can
@@ -1,3 +1,3 @@
1
1
  module AttributesHistory
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -6,22 +6,51 @@ module AttributesHistory
6
6
  module HasAttributesHistory
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ included do
10
+ class_attribute :history_models, :history_associations
11
+ self.history_models ||= {}
12
+ self.history_associations ||= {}
13
+ end
14
+
9
15
  module ClassMethods
10
16
  # The options should include the keys :attributes and :version_class
11
17
  def has_attributes_history(options)
12
- class_attribute :history_model, :history_attributes, :history_association
13
- self.history_model = options[:with_model]
14
- self.history_attributes = options[:for].map(&:to_s)
15
- self.history_association = history_model.name.underscore.pluralize.to_sym
18
+ history_model = options[:with_model]
19
+ history_attributes = options[:for].map(&:to_s)
20
+ history_association = history_model.name.underscore.pluralize.to_sym
16
21
 
17
22
  has_many history_association
18
- after_update { HistorySaver.new(self).save_if_needed }
19
- define_verisons_by_date_lookups
23
+
24
+ store_history_options(history_model, history_attributes, history_association)
25
+ setup_history_callback(history_attributes, history_model)
26
+ define_attribute_on_date_methods(history_attributes)
27
+ end
28
+
29
+ def history_model(attribute)
30
+ self.history_models[attribute]
31
+ end
32
+
33
+ def history_association(attribute)
34
+ self.history_associations[attribute]
20
35
  end
21
36
 
22
37
  private
23
38
 
24
- def define_verisons_by_date_lookups
39
+ def store_history_options(history_model, history_attributes, history_association)
40
+ history_attributes.each do |attribute|
41
+ self.history_associations[attribute] = history_association
42
+ self.history_models[attribute] = history_model
43
+ end
44
+ end
45
+
46
+ def setup_history_callback(history_attributes, history_model)
47
+ after_update do
48
+ HistorySaver.new(self, history_attributes, history_model)
49
+ .save_if_needed
50
+ end
51
+ end
52
+
53
+ def define_attribute_on_date_methods(history_attributes)
25
54
  define_method :attribute_on_date do |attribute, date|
26
55
  @history_retriever ||= HistoryRetriever.new(self)
27
56
  @history_retriever.attribute_on_date(attribute, date)
@@ -6,14 +6,18 @@ module AttributesHistory
6
6
  end
7
7
 
8
8
  def attribute_on_date(attribute, date)
9
- history_entry = @cached_history[date] ||= find_entry_on(date)
9
+ history_association = @object.class.history_association(attribute)
10
+
11
+ history_entry = @cached_history[[history_association, date]] ||=
12
+ find_entry_on(history_association, date)
13
+
10
14
  history_entry.public_send(attribute)
11
15
  end
12
16
 
13
17
  private
14
18
 
15
- def find_entry_on(date)
16
- @object.public_send(@object.history_association)
19
+ def find_entry_on(history_association, date)
20
+ @object.public_send(history_association)
17
21
  .where('recorded_on > ?', date).order(:recorded_on).first || @object
18
22
  end
19
23
  end
@@ -1,7 +1,9 @@
1
1
  module AttributesHistory
2
2
  class HistorySaver
3
- def initialize(changed_object)
3
+ def initialize(changed_object, history_attributes, history_model)
4
4
  @object = changed_object
5
+ @history_attributes = history_attributes
6
+ @history_model = history_model
5
7
  end
6
8
 
7
9
  def save_if_needed
@@ -12,11 +14,14 @@ module AttributesHistory
12
14
  private
13
15
 
14
16
  def history_attributes_changed?
15
- (@object.changed & @object.history_attributes).present?
17
+ (@object.changed & @history_attributes).present?
16
18
  end
17
19
 
18
20
  def save_history_entry
19
- history_entry = @object.public_send(@object.history_association)
21
+ history_association =
22
+ @object.class.history_association(@history_attributes.first)
23
+
24
+ history_entry = @object.public_send(history_association)
20
25
  .find_or_initialize_by(recorded_on: Date.current)
21
26
 
22
27
  # If there is an existing history record for today, just leave it as is,
@@ -25,7 +30,7 @@ module AttributesHistory
25
30
  end
26
31
 
27
32
  def history_params
28
- Hash[@object.history_attributes.map { |f| [f, history_value_for(f)] }]
33
+ Hash[@history_attributes.map { |f| [f, history_value_for(f)] }]
29
34
  end
30
35
 
31
36
  def history_value_for(attribute)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attributes_history
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - draffensperger