paper_trail_scrapbook 0.1.13 → 0.1.15

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c453ce85bdc41cc81c5f1d9f16922ae23c3936d
4
- data.tar.gz: dc47a13264e5bb62434b4e8cd169c78e607b7842
3
+ metadata.gz: 3cd11a4eeaf7c668fe41fe854748cf0f2e8fcaed
4
+ data.tar.gz: a1143aad24dcaa956b19fd47142e7e52b52bc8c4
5
5
  SHA512:
6
- metadata.gz: 1848ed2409a099393b9adf26975d2b35575f742fe18b4d9a8af22108739102ab58aa663b9c28f68f38b7f16a9f007d4c1c759071fcb7b49d9126817d47f23d79
7
- data.tar.gz: 7d9e1dbbf17832aa1e95b82f97efbf4d70d2596f4652b9d88256a56a2fcdb573b5a000236e333522193262681931ee34b8333f060d9be5c1fa143f7e15f265b9
6
+ metadata.gz: 7d8ef81dbaa77a0a90944adc34086ef4482fa6a97304490f4f929520465e7b56398868beb04f0ad433742b2d94fed78d019b63a36603ccd62d08ecba4b022c6a
7
+ data.tar.gz: ff4accb4de852aaacff14195e42b520ee4eac4f3a95370d8e43d24e1aa7492c3afd752af0e68524757438a14cb5383c1f8f256713bfb20c9d51ab8cc6a5962e4
data/Gemfile.lock CHANGED
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paper_trail_scrapbook (0.1.13)
4
+ paper_trail_scrapbook (0.1.15)
5
5
  activerecord
6
6
  adamantium
7
7
  concord
8
- paper_trail (>= 5.2, <= 9.2.0)
8
+ paper_trail (>= 5.2, <= 10.2.1)
9
9
 
10
10
  GEM
11
11
  remote: https://rubygems.org/
@@ -100,11 +100,9 @@ GEM
100
100
  rspec-core (>= 3.4.0, < 3.7.0)
101
101
  nokogiri (1.10.2)
102
102
  mini_portile2 (~> 2.4.0)
103
- paper_trail (9.2.0)
104
- activerecord (>= 4.2, < 5.3)
105
- paper_trail-association_tracking (< 2)
103
+ paper_trail (10.2.1)
104
+ activerecord (>= 4.2, < 6.1)
106
105
  request_store (~> 1.1)
107
- paper_trail-association_tracking (1.1.1)
108
106
  parallel (1.12.1)
109
107
  parser (2.4.0.2)
110
108
  ast (~> 2.3)
data/README.md CHANGED
@@ -60,6 +60,14 @@ end
60
60
  PaperTrailScrapbook.config.whodunnit_class = WhoDidIt
61
61
  ```
62
62
 
63
+ You also have the option of seeing the most recent changes first (default is chronological)
64
+
65
+ ```ruby
66
+
67
+ config.recent_first = true
68
+
69
+ ```
70
+
63
71
  ### Life Story
64
72
 
65
73
  The `LifeStory` module provides a complete history of an object (limited by the
@@ -8,6 +8,11 @@ module PaperTrailScrapbook
8
8
  class Changes
9
9
  include Concord.new(:version)
10
10
  include Adamantium::Flat
11
+ include PaperTrailScrapbook::VersionHelpers
12
+
13
+ POLYMORPH_BT_INDICATOR = '*'
14
+
15
+ delegate :object_changes, to: :version
11
16
 
12
17
  def initialize(*)
13
18
  super
@@ -23,10 +28,11 @@ module PaperTrailScrapbook
23
28
  # @return [String] Summary analysis of changes
24
29
  #
25
30
  def change_log
26
- text = changes
27
- .map { |k, v| digest(k, v) }
28
- .compact
29
- .join("\n")
31
+ text =
32
+ changes
33
+ .map { |k, v| digest(k, v) }
34
+ .compact
35
+ .join("\n")
30
36
 
31
37
  text = text.gsub(' id:', ':') if PaperTrailScrapbook.config.drop_id_suffix
32
38
  text
@@ -34,9 +40,13 @@ module PaperTrailScrapbook
34
40
 
35
41
  private
36
42
 
43
+ def polymorphic?(x)
44
+ x.to_s.start_with?(POLYMORPH_BT_INDICATOR)
45
+ end
46
+
37
47
  def digest(key, values)
38
48
  old, new = values
39
- return if old.nil? && (new.nil? || new.eql?('')) || (old == new)
49
+ return if old.nil? && (new.nil? || new.eql?('')) || (old == new && !creating?)
40
50
 
41
51
  "#{BULLET} #{key.tr('_', ' ')}: #{detailed_analysis(key, new, old)}"
42
52
  end
@@ -63,17 +73,40 @@ module PaperTrailScrapbook
63
73
  return '*empty*' unless value
64
74
 
65
75
  begin
66
- build_associations[key].find(value).to_s.to_s + "[#{value}]"
76
+ assoc_target(key).find(value).to_s.to_s + "[#{value}]"
67
77
  rescue StandardError
68
78
  "*not found*[#{value}]"
69
79
  end
70
80
  end
71
81
 
82
+ def assoc_target(key)
83
+ x = build_associations[key]
84
+ return x unless polymorphic?(x)
85
+ ref = x[1..-1] + '_type'
86
+
87
+ # try object changes to see if the belongs_to class is specified
88
+ latest_class = changes[ref]&.last
89
+
90
+ if latest_class.nil? && create?
91
+ # try the db default class
92
+ # for creates where the object changes do not specify this it
93
+ # is most likely because the default == type selected so
94
+ # the default was not changed and therefore is not in
95
+ # object changes
96
+ orig_instance = Object.const_get(version.item_type.classify).new
97
+ latest_class = orig_instance[ref.to_sym]
98
+ end
99
+
100
+ Object.const_get(latest_class.classify)
101
+ end
102
+
72
103
  def assoc_klass(name, options = {})
73
104
  direct_class = options[:class_name]
74
- return direct_class if direct_class && !direct_class.is_a?(String)
105
+ poly = options[:polymorphic]
106
+
107
+ return direct_class if !poly && direct_class && !direct_class.is_a?(String)
75
108
 
76
- Object.const_get((direct_class || name.to_s).classify)
109
+ poly ? POLYMORPH_BT_INDICATOR + name.to_s : Object.const_get((direct_class || name.to_s).classify)
77
110
  rescue StandardError
78
111
  Object.const_set(name.to_s.classify, Class.new)
79
112
  end
@@ -86,16 +119,12 @@ module PaperTrailScrapbook
86
119
  @build_associations ||=
87
120
  Hash[
88
121
  klass
89
- .reflect_on_all_associations
90
- .select { |a| a.macro.equal?(:belongs_to) }
91
- .map { |x| [x.foreign_key.to_s, assoc_klass(x.name, x.options)] }
122
+ .reflect_on_all_associations
123
+ .select { |a| a.macro.equal?(:belongs_to) }
124
+ .map { |x| [x.foreign_key.to_s, assoc_klass(x.name, x.options)] }
92
125
  ]
93
126
  end
94
127
 
95
- def object_changes
96
- version.object_changes
97
- end
98
-
99
128
  def changes
100
129
  @changes ||= if object_changes
101
130
  YAML
@@ -22,7 +22,8 @@ module PaperTrailScrapbook
22
22
  :drop_id_suffix,
23
23
  :unknown_whodunnit,
24
24
  :invalid_whodunnit,
25
- :filter_non_changes
25
+ :filter_non_changes,
26
+ :recent_first
26
27
 
27
28
  def initialize
28
29
  @whodunnit_class = nil
@@ -33,6 +34,7 @@ module PaperTrailScrapbook
33
34
  @invalid_whodunnit = proc { |w| "*missing (#{w})*" }
34
35
  @drop_id_suffix = true
35
36
  @filter_non_changes = true
37
+ @recent_first = false
36
38
  end
37
39
  end
38
40
  end
@@ -23,13 +23,17 @@ module PaperTrailScrapbook
23
23
  # @return [String] analyzed versions
24
24
  #
25
25
  def story
26
- versions.map do |v|
26
+ x = versions.map do |v|
27
27
  if primary?(v)
28
28
  Chapter
29
29
  else
30
30
  SecondaryChapter
31
31
  end.new(v).story
32
- end.compact.join("\n\n")
32
+ end.compact
33
+
34
+ x.reverse! if PaperTrailScrapbook.config.recent_first
35
+
36
+ x.join("\n\n")
33
37
  end
34
38
 
35
39
  private
@@ -26,7 +26,11 @@ module PaperTrailScrapbook
26
26
  def story
27
27
  s = versions.map do |v|
28
28
  JournalEntry.new(v).story
29
- end.compact.join("\n\n")
29
+ end.compact
30
+
31
+ s.reverse! if PaperTrailScrapbook.config.recent_first
32
+
33
+ s.join("\n\n")
30
34
 
31
35
  "#{preface}#{s.presence || 'No history'}"
32
36
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PaperTrailScrapbook
4
4
  # Current version
5
- VERSION = '0.1.13'
5
+ VERSION = '0.1.15'
6
6
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
21
21
  gem.add_dependency 'activerecord'
22
22
  gem.add_dependency 'adamantium'
23
23
  gem.add_dependency 'concord'
24
- gem.add_dependency 'paper_trail', ['>= 5.2', '<= 9.2.0']
24
+ gem.add_dependency 'paper_trail', ['>= 5.2', '<= 10.2.1']
25
25
 
26
26
  gem.add_development_dependency 'ffaker', '~> 2.5'
27
27
  gem.add_development_dependency 'rake', '~> 10.4.2'
@@ -5,7 +5,7 @@ require 'securerandom'
5
5
  class CustomPrimaryKeyRecord < ActiveRecord::Base
6
6
  self.primary_key = :uuid
7
7
 
8
- has_paper_trail class_name: 'CustomPrimaryKeyRecordVersion'
8
+ has_paper_trail versions: { class_name: 'CustomPrimaryKeyRecordVersion' }
9
9
 
10
10
  # This default_scope is to test the case of the Version#item association
11
11
  # not returning the item due to unmatched default_scope on the model.
@@ -2,7 +2,7 @@
2
2
 
3
3
  class Document < ActiveRecord::Base
4
4
  has_paper_trail(
5
- versions: :paper_trail_versions,
5
+ versions: {name: :paper_trail_versions},
6
6
  on: %i[create update]
7
7
  )
8
8
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kitchen
4
4
  class Banana < ActiveRecord::Base
5
- has_paper_trail class_name: 'Kitchen::BananaVersion'
5
+ has_paper_trail versions: { class_name: 'Kitchen::BananaVersion' }
6
6
  end
7
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Post < ActiveRecord::Base
4
- has_paper_trail class_name: 'PostVersion'
4
+ has_paper_trail versions: { class_name: 'PostVersion' }
5
5
  end
@@ -1,3 +1 @@
1
1
  # frozen_string_literal: true
2
-
3
- PaperTrail.config.track_associations = false
@@ -61,7 +61,7 @@ module PaperTrailScrapbook
61
61
  .to match(/How the Grinch stole Xmas\[\d+\] was \*removed\*/)
62
62
  end
63
63
 
64
- context 'it handles missing whodunnit record' do
64
+ context 'when it handles missing whodunnit record' do
65
65
  it 'provides a whole story with missing whodunnit record' do
66
66
  target
67
67
  pid = person.id
@@ -88,7 +88,7 @@ module PaperTrailScrapbook
88
88
  end
89
89
  end
90
90
 
91
- context 'no papertrail' do
91
+ context 'without papertrail' do
92
92
  let(:target) { Elephant.create! }
93
93
 
94
94
  it 'has none' do
@@ -97,6 +97,15 @@ module PaperTrailScrapbook
97
97
  end
98
98
  end
99
99
 
100
+ context 'with polymorphic data' do
101
+ let(:target) { Whatchamajigger.create!(owner: author) }
102
+
103
+ it 'locates the proper model' do
104
+ expect(subject).to match(/Dr. Seuss\[/)
105
+ expect(subject).to match(/owner type: Person/)
106
+ end
107
+ end
108
+
100
109
  context 'with related data' do
101
110
  before do
102
111
  author
@@ -120,6 +129,42 @@ module PaperTrailScrapbook
120
129
  expect(subject).to match(/author: Dr\. Seuss\[\d+\]/)
121
130
  end
122
131
  end
132
+
133
+ context 'recent first' do
134
+ before do
135
+ author
136
+ book
137
+ target
138
+
139
+ config = PaperTrailScrapbook.config
140
+ config.recent_first = true
141
+ config.time_format = '%A, %d %b %Y at %l:%M:%S.%9N %p'
142
+
143
+ def target.trailed_related_content
144
+ [book, author]
145
+ end
146
+ end
147
+
148
+ after do
149
+ config = PaperTrailScrapbook.config
150
+ config.recent_first = false
151
+ config.time_format = '%A, %d %b %Y at %l:%M %p'
152
+ end
153
+
154
+ it 'includes related content history' do
155
+ expect(subject).to match(/created the following Person\[\d+\] info/)
156
+ expect(subject).to match(/name: Dr\. Seuss/)
157
+
158
+ expect(subject).to match(/created the following Book\[\d+\] info/)
159
+ expect(subject).to match(/title: How the Grinch stole Xmas/)
160
+
161
+ expect(subject.squish).to match(/created the following Book.*created the following Person/)
162
+
163
+ expect(subject).to match(/created the following Authorship info/)
164
+ expect(subject).to match(/book: How the Grinch stole Xmas\[\d+\]/)
165
+ expect(subject).to match(/author: Dr\. Seuss\[\d+\]/)
166
+ end
167
+ end
123
168
  end
124
169
  end
125
170
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail_scrapbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timothy Chambers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-28 00:00:00.000000000 Z
11
+ date: 2019-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '5.2'
62
62
  - - "<="
63
63
  - !ruby/object:Gem::Version
64
- version: 9.2.0
64
+ version: 10.2.1
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,7 +71,7 @@ dependencies:
71
71
  version: '5.2'
72
72
  - - "<="
73
73
  - !ruby/object:Gem::Version
74
- version: 9.2.0
74
+ version: 10.2.1
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: ffaker
77
77
  requirement: !ruby/object:Gem::Requirement