paper_trail_scrapbook 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +21 -0
  3. data/.rspec +5 -0
  4. data/.rubocop.yml +8 -0
  5. data/.ruby-gemset +1 -0
  6. data/Changelog.md +0 -0
  7. data/Gemfile +3 -0
  8. data/Gemfile.lock +141 -0
  9. data/LICENSE.md +21 -0
  10. data/README.md +77 -0
  11. data/Rakefile +24 -0
  12. data/circle.yml +10 -0
  13. data/lib/paper_trail_scrapbook/changes.rb +89 -0
  14. data/lib/paper_trail_scrapbook/chapter.rb +49 -0
  15. data/lib/paper_trail_scrapbook/config.rb +13 -0
  16. data/lib/paper_trail_scrapbook/life_history.rb +17 -0
  17. data/lib/paper_trail_scrapbook/version.rb +4 -0
  18. data/lib/paper_trail_scrapbook.rb +51 -0
  19. data/paper_trail_scrapbook.gemspec +38 -0
  20. data/spec/dummy_app/Rakefile +7 -0
  21. data/spec/dummy_app/app/models/animal.rb +4 -0
  22. data/spec/dummy_app/app/models/article.rb +24 -0
  23. data/spec/dummy_app/app/models/authorship.rb +5 -0
  24. data/spec/dummy_app/app/models/bar_habtm.rb +4 -0
  25. data/spec/dummy_app/app/models/book.rb +9 -0
  26. data/spec/dummy_app/app/models/boolit.rb +4 -0
  27. data/spec/dummy_app/app/models/callback_modifier.rb +45 -0
  28. data/spec/dummy_app/app/models/car.rb +3 -0
  29. data/spec/dummy_app/app/models/cat.rb +2 -0
  30. data/spec/dummy_app/app/models/chapter.rb +9 -0
  31. data/spec/dummy_app/app/models/citation.rb +5 -0
  32. data/spec/dummy_app/app/models/custom_primary_key_record.rb +15 -0
  33. data/spec/dummy_app/app/models/customer.rb +4 -0
  34. data/spec/dummy_app/app/models/document.rb +6 -0
  35. data/spec/dummy_app/app/models/dog.rb +2 -0
  36. data/spec/dummy_app/app/models/editor.rb +4 -0
  37. data/spec/dummy_app/app/models/editorship.rb +5 -0
  38. data/spec/dummy_app/app/models/elephant.rb +3 -0
  39. data/spec/dummy_app/app/models/fluxor.rb +3 -0
  40. data/spec/dummy_app/app/models/foo_habtm.rb +5 -0
  41. data/spec/dummy_app/app/models/foo_widget.rb +2 -0
  42. data/spec/dummy_app/app/models/fruit.rb +5 -0
  43. data/spec/dummy_app/app/models/gadget.rb +3 -0
  44. data/spec/dummy_app/app/models/kitchen/banana.rb +5 -0
  45. data/spec/dummy_app/app/models/legacy_widget.rb +3 -0
  46. data/spec/dummy_app/app/models/line_item.rb +4 -0
  47. data/spec/dummy_app/app/models/not_on_update.rb +4 -0
  48. data/spec/dummy_app/app/models/on/create.rb +6 -0
  49. data/spec/dummy_app/app/models/on/destroy.rb +6 -0
  50. data/spec/dummy_app/app/models/on/empty_array.rb +6 -0
  51. data/spec/dummy_app/app/models/on/update.rb +6 -0
  52. data/spec/dummy_app/app/models/order.rb +5 -0
  53. data/spec/dummy_app/app/models/paragraph.rb +5 -0
  54. data/spec/dummy_app/app/models/person.rb +39 -0
  55. data/spec/dummy_app/app/models/post.rb +3 -0
  56. data/spec/dummy_app/app/models/post_with_status.rb +7 -0
  57. data/spec/dummy_app/app/models/quotation.rb +5 -0
  58. data/spec/dummy_app/app/models/section.rb +6 -0
  59. data/spec/dummy_app/app/models/skipper.rb +3 -0
  60. data/spec/dummy_app/app/models/song.rb +37 -0
  61. data/spec/dummy_app/app/models/thing.rb +3 -0
  62. data/spec/dummy_app/app/models/translation.rb +6 -0
  63. data/spec/dummy_app/app/models/truck.rb +4 -0
  64. data/spec/dummy_app/app/models/vehicle.rb +4 -0
  65. data/spec/dummy_app/app/models/whatchamajigger.rb +4 -0
  66. data/spec/dummy_app/app/models/widget.rb +8 -0
  67. data/spec/dummy_app/app/models/wotsit.rb +8 -0
  68. data/spec/dummy_app/app/versions/custom_primary_key_record_version.rb +3 -0
  69. data/spec/dummy_app/app/versions/joined_version.rb +6 -0
  70. data/spec/dummy_app/app/versions/json_version.rb +3 -0
  71. data/spec/dummy_app/app/versions/kitchen/banana_version.rb +5 -0
  72. data/spec/dummy_app/app/versions/post_version.rb +3 -0
  73. data/spec/dummy_app/config/application.rb +37 -0
  74. data/spec/dummy_app/config/boot.rb +24 -0
  75. data/spec/dummy_app/config/database.sqlite.yml +15 -0
  76. data/spec/dummy_app/config/database.yml +15 -0
  77. data/spec/dummy_app/config/environment.rb +5 -0
  78. data/spec/dummy_app/config/environments/development.rb +36 -0
  79. data/spec/dummy_app/config/environments/production.rb +74 -0
  80. data/spec/dummy_app/config/environments/test.rb +46 -0
  81. data/spec/dummy_app/config/initializers/backtrace_silencers.rb +9 -0
  82. data/spec/dummy_app/config/initializers/inflections.rb +10 -0
  83. data/spec/dummy_app/config/initializers/mime_types.rb +5 -0
  84. data/spec/dummy_app/config/initializers/paper_trail.rb +1 -0
  85. data/spec/dummy_app/config/initializers/secret_token.rb +9 -0
  86. data/spec/dummy_app/config/initializers/session_store.rb +8 -0
  87. data/spec/dummy_app/config/locales/en.yml +5 -0
  88. data/spec/dummy_app/config/routes.rb +4 -0
  89. data/spec/dummy_app/config.ru +4 -0
  90. data/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb +344 -0
  91. data/spec/dummy_app/db/schema.rb +296 -0
  92. data/spec/dummy_app/db/test.sqlite3 +0 -0
  93. data/spec/paper_trail_scrapbook/changes_spec.rb +6 -0
  94. data/spec/paper_trail_scrapbook/chapter_spec.rb +6 -0
  95. data/spec/paper_trail_scrapbook/config_spec.rb +17 -0
  96. data/spec/paper_trail_scrapbook/life_history_spec.rb +6 -0
  97. data/spec/paper_trail_scrapbook/version_spec.rb +6 -0
  98. data/spec/paper_trail_scrapbook_spec.rb +4 -0
  99. data/spec/spec_helper.rb +73 -0
  100. metadata +363 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2227bf7cf82738d74887b11e4017a52950b5f774
4
+ data.tar.gz: 20465a690da01b2f9073059870e9e37e8ed3b0ee
5
+ SHA512:
6
+ metadata.gz: a50ecc1b54b77918bf1aed69156f6f0c7fe93ebba4bf3fe6c589a25f57ff6141af992679eb2128e5199e0013514a12b36bd235740c6f44c8c71233d82f23e1a8
7
+ data.tar.gz: 1b9d471bc89bd8f6f906aba1538d41c9727274add361110fb744d40b11c4072973b14f7beee2a815c6f62986f2217bf38597c54fd43ba262bd6226deb4d30cd9
data/.codeclimate.yml ADDED
@@ -0,0 +1,21 @@
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - ruby
8
+ fixme:
9
+ enabled: true
10
+ rubocop:
11
+ enabled: true
12
+ ratings:
13
+ paths:
14
+ - "**.inc"
15
+ - "**.js"
16
+ - "**.jsx"
17
+ - "**.module"
18
+ - "**.php"
19
+ - "**.py"
20
+ - "**.rb"
21
+ exclude_paths: []
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --require spec_helper
3
+ --format progress
4
+ --warnings
5
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ DisabledByDefault: false
3
+ TargetRubyVersion: 2.2
4
+ TargetRailsVersion: 4.0
5
+ DisplayCopNames: true
6
+
7
+ Security/YAMLLoad:
8
+ Enabled: false
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ paper_trail_scrapbook
data/Changelog.md ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec # DRY! No need to repeat the gem deps here
data/Gemfile.lock ADDED
@@ -0,0 +1,141 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ paper_trail_scrapbook (0.0.2)
5
+ activerecord (>= 4.0, < 5.2)
6
+ adamantium
7
+ concord
8
+ paper_trail
9
+ request_store (~> 1.1)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ actionpack (5.1.2)
15
+ actionview (= 5.1.2)
16
+ activesupport (= 5.1.2)
17
+ rack (~> 2.0)
18
+ rack-test (~> 0.6.3)
19
+ rails-dom-testing (~> 2.0)
20
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
21
+ actionview (5.1.2)
22
+ activesupport (= 5.1.2)
23
+ builder (~> 3.1)
24
+ erubi (~> 1.4)
25
+ rails-dom-testing (~> 2.0)
26
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
27
+ activemodel (5.1.2)
28
+ activesupport (= 5.1.2)
29
+ activerecord (5.1.2)
30
+ activemodel (= 5.1.2)
31
+ activesupport (= 5.1.2)
32
+ arel (~> 8.0)
33
+ activesupport (5.1.2)
34
+ concurrent-ruby (~> 1.0, >= 1.0.2)
35
+ i18n (~> 0.7)
36
+ minitest (~> 5.1)
37
+ tzinfo (~> 1.1)
38
+ adamantium (0.2.0)
39
+ ice_nine (~> 0.11.0)
40
+ memoizable (~> 0.4.0)
41
+ arel (8.0.0)
42
+ ast (2.3.0)
43
+ builder (3.2.3)
44
+ concord (0.1.5)
45
+ adamantium (~> 0.2.0)
46
+ equalizer (~> 0.0.9)
47
+ concurrent-ruby (1.0.5)
48
+ database_cleaner (1.6.1)
49
+ diff-lcs (1.3)
50
+ equalizer (0.0.11)
51
+ erubi (1.6.1)
52
+ ffaker (2.6.0)
53
+ i18n (0.8.4)
54
+ ice_nine (0.11.2)
55
+ loofah (2.0.3)
56
+ nokogiri (>= 1.5.9)
57
+ memoizable (0.4.2)
58
+ thread_safe (~> 0.3, >= 0.3.1)
59
+ method_source (0.8.2)
60
+ mini_portile2 (2.2.0)
61
+ minitest (5.10.2)
62
+ nokogiri (1.8.0)
63
+ mini_portile2 (~> 2.2.0)
64
+ paper_trail (7.0.3)
65
+ activerecord (>= 4.0, < 5.2)
66
+ request_store (~> 1.1)
67
+ parallel (1.11.2)
68
+ parser (2.4.0.0)
69
+ ast (~> 2.2)
70
+ powerpack (0.1.1)
71
+ rack (2.0.3)
72
+ rack-test (0.6.3)
73
+ rack (>= 1.0)
74
+ rails-dom-testing (2.0.3)
75
+ activesupport (>= 4.2.0)
76
+ nokogiri (>= 1.6)
77
+ rails-html-sanitizer (1.0.3)
78
+ loofah (~> 2.0)
79
+ railties (5.1.2)
80
+ actionpack (= 5.1.2)
81
+ activesupport (= 5.1.2)
82
+ method_source
83
+ rake (>= 0.8.7)
84
+ thor (>= 0.18.1, < 2.0)
85
+ rainbow (2.2.2)
86
+ rake
87
+ rake (12.0.0)
88
+ request_store (1.3.2)
89
+ rspec-core (3.6.0)
90
+ rspec-support (~> 3.6.0)
91
+ rspec-expectations (3.6.0)
92
+ diff-lcs (>= 1.2.0, < 2.0)
93
+ rspec-support (~> 3.6.0)
94
+ rspec-mocks (3.6.0)
95
+ diff-lcs (>= 1.2.0, < 2.0)
96
+ rspec-support (~> 3.6.0)
97
+ rspec-rails (3.6.0)
98
+ actionpack (>= 3.0)
99
+ activesupport (>= 3.0)
100
+ railties (>= 3.0)
101
+ rspec-core (~> 3.6.0)
102
+ rspec-expectations (~> 3.6.0)
103
+ rspec-mocks (~> 3.6.0)
104
+ rspec-support (~> 3.6.0)
105
+ rspec-support (3.6.0)
106
+ rubocop (0.49.1)
107
+ parallel (~> 1.10)
108
+ parser (>= 2.3.3.1, < 3.0)
109
+ powerpack (~> 0.1)
110
+ rainbow (>= 1.99.1, < 3.0)
111
+ ruby-progressbar (~> 1.7)
112
+ unicode-display_width (~> 1.0, >= 1.0.1)
113
+ rubocop-rspec (1.15.1)
114
+ rubocop (>= 0.42.0)
115
+ ruby-progressbar (1.8.1)
116
+ sqlite3 (1.3.13)
117
+ thor (0.19.4)
118
+ thread_safe (0.3.6)
119
+ timecop (0.8.1)
120
+ tzinfo (1.2.3)
121
+ thread_safe (~> 0.1)
122
+ unicode-display_width (1.3.0)
123
+
124
+ PLATFORMS
125
+ ruby
126
+
127
+ DEPENDENCIES
128
+ database_cleaner (~> 1.2)
129
+ ffaker (~> 2.5)
130
+ paper_trail_scrapbook!
131
+ railties (>= 4.0, < 5.2)
132
+ rake (~> 12.0)
133
+ rspec-core (~> 3.6)
134
+ rspec-rails (~> 3.6)
135
+ rubocop
136
+ rubocop-rspec
137
+ sqlite3
138
+ timecop (~> 0.8.0)
139
+
140
+ BUNDLED WITH
141
+ 1.15.1
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Tim Chambers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Paper Trail Scrapbook
2
+
3
+ [![CircleCI](https://circleci.com/gh/tjchambers/paper_trail_scrapbook/tree/master.svg?style=svg)](https://circleci.com/gh/tjchambers/paper_trail_scrapbook/tree/master)
4
+
5
+ Human Readable audit reporting for users of [PaperTrail](https://github.com/airblade/paper_trail) gem.
6
+
7
+ ## Installation
8
+
9
+ Add PaperTrailScrapBook to your `Gemfile`.
10
+
11
+ `gem 'paper_trail_scrapbook'`
12
+
13
+ ## Basic Usage
14
+
15
+ ### Configuration
16
+
17
+ If you are using a ID of some sort to a class (i.e. _User_) for whodunnit in PaperTrail
18
+ then you should configure this into the scrapbook so it can locate and provide a human readable value for the whodunnit.
19
+
20
+ Create an initializer i.e. _config/initializers/paper_trail_scrapbook.rb
21
+ ```ruby
22
+ PaperTrailScrapbook.config.whodunnit_class = User
23
+
24
+ ```
25
+
26
+ This gem will call `find` on that class, and translate the result to a
27
+ String via `to_s`, so it can be a simple Rails model, or a custom Ruby class that has `find` class method and
28
+ expects the `whodunnit` value. For example
29
+
30
+ ```ruby
31
+ class WhoDidIt
32
+ def self.find(email)
33
+ Person.find_by(email: email)
34
+ end
35
+ end
36
+
37
+
38
+ PaperTrailScrapbook.config.whodunnit_class = WhoDidIt
39
+
40
+ ```
41
+
42
+ ### Life Story
43
+ ```ruby
44
+ widget = Widget.find 42
45
+
46
+ text = PaperTrailScrapbook::LifeStory.new(widget).story
47
+ # On Wednesday, 07 Jun 2017 at 2:37 PM, Rob Owens created the following Widget information:
48
+ # • email: Tim@example.com
49
+ # • name: Tim's Widget
50
+ # • built: true
51
+ # • created_by: Rob Owens[1742]
52
+ # • provider: RedCharge[3113]
53
+ # • cost: 29612.0
54
+ # • discounted_price: 29612.0
55
+ ```
56
+
57
+ ## Problems
58
+
59
+ Please use GitHub's [issue tracker](http://github.com/tjchambers/paper_trail_scrapbook/issues).
60
+
61
+ ## Contributors
62
+
63
+ Created by Tim Chambers in 2017.
64
+
65
+ https://github.com/tjchambers/paper_trail_scrapbook/graphs/contributors
66
+
67
+ Acknowledgement and kudos to Andy Stewart, Ben Atkins, Jared Beck, and all the other contributors to the PaperTrail gem.
68
+ Without them this would not be possible.
69
+
70
+
71
+ ## Intellectual Property
72
+
73
+ Copyright (c) 2017 Tim Chambers (tim@possibilogy.com).
74
+ Released under the MIT licence.
75
+
76
+
77
+
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ desc 'Set a relevant database.yml for testing'
5
+ task :prepare do
6
+ ENV['DB'] ||= 'sqlite'
7
+ FileUtils.cp(
8
+ "spec/dummy_app/config/database.#{ENV['DB']}.yml",
9
+ 'spec/dummy_app/config/database.yml'
10
+ )
11
+ end
12
+
13
+ require 'rspec/core/rake_task'
14
+ desc 'Run tests on PaperTrailScrapbook with RSpec'
15
+ task(:spec).clear
16
+ RSpec::Core::RakeTask.new(:spec) do |t|
17
+ t.verbose = false # hide list of specs bit.ly/1nVq3Jn
18
+ end
19
+
20
+ require 'rubocop/rake_task'
21
+ RuboCop::RakeTask.new
22
+
23
+ desc 'Default: run all available test suites'
24
+ task default: %i[rubocop prepare spec]
data/circle.yml ADDED
@@ -0,0 +1,10 @@
1
+ ---
2
+ machine:
3
+ ruby:
4
+ version: '2.2.7'
5
+ dependencies:
6
+ pre:
7
+ - gem install bundler
8
+ test:
9
+ override:
10
+ - bundle exec rake spec
@@ -0,0 +1,89 @@
1
+ module PaperTrailScrapbook
2
+ class Changes
3
+ include Concord.new(:version)
4
+
5
+ def initialize(*)
6
+ super
7
+
8
+ build_associations
9
+ end
10
+
11
+ BULLET = ' •'.freeze
12
+
13
+ def change_log
14
+ changes.map { |k, v| digest(k, v) }.compact.join("\n").gsub('_id:', ':')
15
+ end
16
+
17
+ private
18
+
19
+ def digest(k, v)
20
+ old, new = v
21
+ return if old.nil? && (new.nil? || new.eql?(''))
22
+
23
+ "#{BULLET} #{k}: " + if creating?
24
+ find_value(k, new).to_s
25
+ elsif old.nil?
26
+ "#{find_value(k, new)} added"
27
+ elsif new.nil?
28
+ "#{find_value(k, old)} was *removed*"
29
+ else
30
+ "#{find_value(k, old)} -> #{find_value(k, new)}"
31
+ end
32
+ end
33
+
34
+ def creating?
35
+ version.event.eql?('create')
36
+ end
37
+
38
+ def find_value(key, value)
39
+ return value.to_s unless assoc.key?(key)
40
+
41
+ return '*empty*' unless value
42
+
43
+ begin
44
+ assoc[key].find(value).to_s + "[#{value}]"
45
+ rescue
46
+ "*not found*[#{value}]"
47
+ end
48
+ end
49
+
50
+ def assoc_klass(name, options = {})
51
+ direct_class = options[:class_name]
52
+ return direct_class if direct_class && !direct_class.is_a?(String)
53
+
54
+ Object.const_get((direct_class || name.to_s).classify)
55
+ rescue
56
+ Object.const_set(name.to_s.classify, Class.new)
57
+ end
58
+
59
+ def klass
60
+ assoc_klass(version.item_type)
61
+ end
62
+
63
+ def build_associations
64
+ @assoc ||=
65
+ Hash[
66
+ klass
67
+ .reflect_on_all_associations
68
+ .select { |a| a.macro.equal?(:belongs_to) }
69
+ .map { |x| [x.foreign_key.to_s, assoc_klass(x.name, x.options)] }
70
+ ]
71
+ end
72
+
73
+ def object_changes
74
+ version.object_changes
75
+ end
76
+
77
+ def changes
78
+ @chs ||= if object_changes
79
+ YAML
80
+ .load(object_changes)
81
+ .except('updated_at', 'created_at ', 'id')
82
+ else
83
+ {}
84
+ end
85
+ end
86
+
87
+ attr_reader :assoc, :chs
88
+ end
89
+ end
@@ -0,0 +1,49 @@
1
+ module PaperTrailScrapbook
2
+ class Chapter
3
+ include Concord.new(:version)
4
+
5
+ UNKNOWN = '*the app*'.freeze
6
+
7
+ def story
8
+ "On #{whenn}, #{who} #{kind} the following #{model} information:".split.join(' ') + "\n#{changes}"
9
+ end
10
+
11
+ private
12
+
13
+ def model
14
+ version.item_type
15
+ end
16
+
17
+ def changes
18
+ PaperTrailScrapbook::Changes.new(version).change_log
19
+ end
20
+
21
+ def who
22
+ author = version.version_author
23
+ if author
24
+ if PaperTrailScrapbook.whodunnit_class
25
+ PaperTrailScrapbook.whodunnit_class.find(author.to_i).to_s
26
+ else
27
+ author
28
+ end
29
+ else
30
+ UNKNOWN
31
+ end
32
+ end
33
+
34
+ def whenn
35
+ version.created_at.strftime('%A, %d %b %Y at %l:%M %p')
36
+ end
37
+
38
+ def kind
39
+ case version.event
40
+ when 'create'
41
+ 'created'
42
+ when 'update'
43
+ 'updated'
44
+ when 'destroy'
45
+ 'destroyed'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ require 'singleton'
2
+
3
+ module PaperTrailScrapbook
4
+ # Global configuration affecting all threads.
5
+ class Config
6
+ include Singleton
7
+
8
+ def initialize
9
+ # Variables which affect all threads, whose access is synchronized.
10
+ @mutex = Mutex.new
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module PaperTrailScrapbook
2
+ class LifeHistory
3
+ def initialize(object)
4
+ @versions = object.versions
5
+ end
6
+
7
+ def story
8
+ versions.map do |v|
9
+ Chapter.new(v).story
10
+ end.join("\n\n")
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :versions
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ module PaperTrailScrapbook
2
+ # Current version
3
+ VERSION = '0.0.2'.freeze
4
+ end
@@ -0,0 +1,51 @@
1
+ require 'adamantium'
2
+ require 'concord'
3
+ require 'digest/sha1'
4
+ require 'equalizer'
5
+ require 'ice_nine'
6
+ require 'pathname'
7
+ require 'paper_trail_scrapbook/config'
8
+ require 'paper_trail_scrapbook/chapter'
9
+ require 'paper_trail_scrapbook/changes'
10
+ require 'paper_trail_scrapbook/life_history'
11
+ require 'paper_trail_scrapbook/version'
12
+
13
+ # Library namespace
14
+ #
15
+ # @api private
16
+ module PaperTrailScrapbook
17
+ class << self
18
+ # Sets class associated with PaperTrail.whodunnit
19
+ # @api public
20
+ def whodunnit_class=(value)
21
+ paper_trail_scrapbook_store[:whodunnit_class] = value
22
+ end
23
+
24
+ # class responsible for any changes that occur.
25
+ #
26
+ # @api public
27
+ def whodunnit_class
28
+ paper_trail_scrapbook_store[:whodunnit_class]
29
+ end
30
+
31
+ # Thread-safe hash to hold PaperTrailScrapbook's data. Initializing with needed
32
+ # default values.
33
+ # @api private
34
+ def paper_trail_scrapbook_store
35
+ RequestStore.store[:paper_trail_scrapbook] ||= {}
36
+ end
37
+
38
+ # Returns PaperTrailScrapbook's configuration object.
39
+ # @api private
40
+ def config
41
+ @config ||= PaperTrailScrapbook::Config.instance
42
+ yield @config if block_given?
43
+ @config
44
+ end
45
+ alias configure config
46
+
47
+ def version
48
+ VERSION::STRING
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../lib/paper_trail_scrapbook/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'paper_trail_scrapbook'
5
+ gem.version = PaperTrailScrapbook::VERSION.dup
6
+ gem.date = Time.now.utc.strftime('%Y-%m-%d')
7
+ gem.summary = 'Paper Trail Scrapbook'
8
+ gem.description = "Human Readable Change Log for Paper Trail'd data"
9
+ gem.authors = ['Timothy Chambers']
10
+ gem.email = 'tim@possibilogy.com'
11
+ gem.files = `git ls-files`.split("\n")
12
+ gem.homepage = 'https://github.com/tjchambers/paper_trail_scrapbook'
13
+ gem.license = 'MIT'
14
+
15
+ gem.required_rubygems_version = '>= 1.3.6'
16
+ gem.required_ruby_version = '>= 2.2.0'
17
+
18
+ # Rails does not follow semver, makes breaking changes in minor versions.
19
+ gem.add_dependency 'activerecord', ['>= 4.0', '< 5.2']
20
+ gem.add_dependency 'request_store', '~> 1.1'
21
+ gem.add_dependency 'adamantium'
22
+ gem.add_dependency 'concord'
23
+ gem.add_dependency 'paper_trail'
24
+
25
+ gem.add_development_dependency 'rake', '~> 12.0'
26
+ gem.add_development_dependency 'ffaker', '~> 2.5'
27
+
28
+ # Why `railties`? Possibly used by `spec/dummy_app` boot up?
29
+ gem.add_development_dependency 'railties', ['>= 4.0', '< 5.2']
30
+
31
+ gem.add_development_dependency 'rspec-rails', '~> 3.6'
32
+ gem.add_development_dependency 'rspec-core', '~> 3.6'
33
+ gem.add_development_dependency 'database_cleaner', '~> 1.2'
34
+ gem.add_development_dependency 'rubocop'
35
+ gem.add_development_dependency 'rubocop-rspec'
36
+ gem.add_development_dependency 'timecop', '~> 0.8.0'
37
+ gem.add_development_dependency 'sqlite3'
38
+ end
@@ -0,0 +1,7 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+ require 'rake'
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,4 @@
1
+ class Animal < ActiveRecord::Base
2
+ has_paper_trail
3
+ self.inheritance_column = 'species'
4
+ end
@@ -0,0 +1,24 @@
1
+ class Article < ActiveRecord::Base
2
+ has_paper_trail(
3
+ ignore: [
4
+ :title, {
5
+ abstract: proc { |obj|
6
+ ['ignore abstract', 'Other abstract'].include? obj.abstract
7
+ }
8
+ }
9
+ ],
10
+ only: [:content, { abstract: proc { |obj| obj.abstract.present? } }],
11
+ skip: [:file_upload],
12
+ meta: {
13
+ answer: 42,
14
+ action: :action_data_provider_method,
15
+ question: proc { "31 + 11 = #{31 + 11}" },
16
+ article_id: proc { |article| article.id },
17
+ title: :title
18
+ }
19
+ )
20
+
21
+ def action_data_provider_method
22
+ object_id.to_s
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ class Authorship < ActiveRecord::Base
2
+ belongs_to :book
3
+ belongs_to :author, class_name: 'Person'
4
+ has_paper_trail
5
+ end
@@ -0,0 +1,4 @@
1
+ class BarHabtm < ActiveRecord::Base
2
+ has_and_belongs_to_many :foo_habtms
3
+ has_paper_trail
4
+ end
@@ -0,0 +1,9 @@
1
+ class Book < ActiveRecord::Base
2
+ has_many :authorships, dependent: :destroy
3
+ has_many :authors, through: :authorships
4
+
5
+ has_many :editorships, dependent: :destroy
6
+ has_many :editors, through: :editorships
7
+
8
+ has_paper_trail
9
+ end
@@ -0,0 +1,4 @@
1
+ class Boolit < ActiveRecord::Base
2
+ default_scope { where(scoped: true) }
3
+ has_paper_trail
4
+ end