paper_trail_manager 0.7.0 → 0.8.0
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 +4 -4
- data/.github/workflows/test.yml +13 -47
- data/.gitignore +2 -2
- data/.ruby-version +1 -0
- data/Appraisals +9 -17
- data/CHANGES.md +18 -0
- data/README.md +130 -66
- data/Rakefile +5 -3
- data/app/controllers/paper_trail_manager/changes_controller.rb +16 -1
- data/app/helpers/paper_trail_manager/changes_helper.rb +2 -2
- data/app/views/paper_trail_manager/changes/_version.html.erb +1 -1
- data/app/views/paper_trail_manager/changes/index.html.erb +41 -28
- data/app/views/paper_trail_manager/changes/show.html.erb +9 -6
- data/gemfiles/rails_6.1_paper_trail_12.0_kaminari.gemfile +10 -0
- data/gemfiles/rails_6.1_paper_trail_12.0_will_paginate.gemfile +10 -0
- data/gemfiles/rails_7.0_paper_trail_12.0_kaminari.gemfile +10 -0
- data/gemfiles/rails_7.0_paper_trail_12.0_will_paginate.gemfile +10 -0
- data/gemfiles/rails_7.0_paper_trail_15.0_kaminari.gemfile +10 -0
- data/gemfiles/rails_7.0_paper_trail_15.0_will_paginate.gemfile +10 -0
- data/gemfiles/rails_7.1_paper_trail_15.0_kaminari.gemfile +10 -0
- data/gemfiles/rails_7.1_paper_trail_15.0_will_paginate.gemfile +10 -0
- data/lib/paper_trail_manager.rb +4 -2
- data/paper_trail_manager.gemspec +14 -14
- data/spec/app_template.rb +19 -10
- data/spec/integration/authorization_spec.rb +84 -0
- data/spec/integration/date_filter_spec.rb +84 -0
- data/spec/integration/navigation_spec.rb +1 -1
- data/spec/integration/paper_trail_manager_spec.rb +6 -6
- data/spec/integration/response_formats_spec.rb +73 -0
- data/spec/support/factories.rb +2 -2
- data/spec/unit/authorization_spec.rb +42 -0
- data/spec/unit/changes_helper_spec.rb +81 -0
- metadata +75 -59
- data/gemfiles/rails_4.2.2_paper_trail_3.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_3.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_4.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_4.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_5.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_5.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_6.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_6.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_7.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_7.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_8.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_4.2.2_paper_trail_8.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_5.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_5.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_6.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_6.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_7.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_7.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_8.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.0.0_paper_trail_8.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_10.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_10.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_7.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_7.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_8.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_8.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_9.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.1.0_paper_trail_9.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.2.0_paper_trail_10.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.2.0_paper_trail_10.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_5.2.0_paper_trail_9.0_kaminari.gemfile +0 -13
- data/gemfiles/rails_5.2.0_paper_trail_9.0_will_paginate.gemfile +0 -13
- data/gemfiles/rails_6.0.0_paper_trail_10.0_kaminari.gemfile +0 -14
- data/gemfiles/rails_6.0.0_paper_trail_10.0_will_paginate.gemfile +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 007f0fa99ee11e2fdd0d615ec29d66e74788062b3a8e479091c31427d54add6c
|
|
4
|
+
data.tar.gz: a71dfd4c73909f185c580a11eae304ac0fb75e8c16fe92fe890ddeb90d7ace71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b019f63c912f3627025427264b6b48be3347e8fe9ec1145ee1b97347e807e0d5642ff6c06ec5085635d6fe5d18354397865bc85734ade8c015284fa484287220
|
|
7
|
+
data.tar.gz: 0f60e85a369b84075a088f2e2cbca20d85895c7ff42c38fcb7d1595f7e503954bd5ea3c19cfa8b393b433ab003e4309f367caeb03dc3997e2e7f913fda167220
|
data/.github/workflows/test.yml
CHANGED
|
@@ -19,64 +19,30 @@ jobs:
|
|
|
19
19
|
fail-fast: false
|
|
20
20
|
matrix:
|
|
21
21
|
ruby:
|
|
22
|
-
-
|
|
23
|
-
- 2
|
|
22
|
+
- '3.1'
|
|
23
|
+
- '3.2'
|
|
24
|
+
- '3.3'
|
|
24
25
|
gemfile:
|
|
25
|
-
- gemfiles/
|
|
26
|
-
- gemfiles/
|
|
27
|
-
- gemfiles/
|
|
28
|
-
- gemfiles/
|
|
29
|
-
- gemfiles/
|
|
30
|
-
- gemfiles/
|
|
31
|
-
- gemfiles/rails_4.2.2_paper_trail_6.0_kaminari.gemfile
|
|
32
|
-
- gemfiles/rails_4.2.2_paper_trail_6.0_will_paginate.gemfile
|
|
33
|
-
- gemfiles/rails_4.2.2_paper_trail_7.0_kaminari.gemfile
|
|
34
|
-
- gemfiles/rails_4.2.2_paper_trail_7.0_will_paginate.gemfile
|
|
35
|
-
- gemfiles/rails_4.2.2_paper_trail_8.0_kaminari.gemfile
|
|
36
|
-
- gemfiles/rails_4.2.2_paper_trail_8.0_will_paginate.gemfile
|
|
37
|
-
- gemfiles/rails_5.0.0_paper_trail_5.0_kaminari.gemfile
|
|
38
|
-
- gemfiles/rails_5.0.0_paper_trail_5.0_will_paginate.gemfile
|
|
39
|
-
- gemfiles/rails_5.0.0_paper_trail_6.0_kaminari.gemfile
|
|
40
|
-
- gemfiles/rails_5.0.0_paper_trail_6.0_will_paginate.gemfile
|
|
41
|
-
- gemfiles/rails_5.0.0_paper_trail_7.0_kaminari.gemfile
|
|
42
|
-
- gemfiles/rails_5.0.0_paper_trail_7.0_will_paginate.gemfile
|
|
43
|
-
- gemfiles/rails_5.0.0_paper_trail_8.0_kaminari.gemfile
|
|
44
|
-
- gemfiles/rails_5.0.0_paper_trail_8.0_will_paginate.gemfile
|
|
45
|
-
- gemfiles/rails_5.1.0_paper_trail_10.0_kaminari.gemfile
|
|
46
|
-
- gemfiles/rails_5.1.0_paper_trail_10.0_will_paginate.gemfile
|
|
47
|
-
- gemfiles/rails_5.1.0_paper_trail_7.0_kaminari.gemfile
|
|
48
|
-
- gemfiles/rails_5.1.0_paper_trail_7.0_will_paginate.gemfile
|
|
49
|
-
- gemfiles/rails_5.1.0_paper_trail_8.0_kaminari.gemfile
|
|
50
|
-
- gemfiles/rails_5.1.0_paper_trail_8.0_will_paginate.gemfile
|
|
51
|
-
- gemfiles/rails_5.1.0_paper_trail_9.0_kaminari.gemfile
|
|
52
|
-
- gemfiles/rails_5.1.0_paper_trail_9.0_will_paginate.gemfile
|
|
53
|
-
- gemfiles/rails_5.2.0_paper_trail_10.0_kaminari.gemfile
|
|
54
|
-
- gemfiles/rails_5.2.0_paper_trail_10.0_will_paginate.gemfile
|
|
55
|
-
- gemfiles/rails_5.2.0_paper_trail_9.0_kaminari.gemfile
|
|
56
|
-
- gemfiles/rails_5.2.0_paper_trail_9.0_will_paginate.gemfile
|
|
57
|
-
- gemfiles/rails_6.0.0_paper_trail_10.0_kaminari.gemfile
|
|
58
|
-
- gemfiles/rails_6.0.0_paper_trail_10.0_will_paginate.gemfile
|
|
26
|
+
- gemfiles/rails_7.0_paper_trail_12.0_kaminari.gemfile
|
|
27
|
+
- gemfiles/rails_7.0_paper_trail_12.0_will_paginate.gemfile
|
|
28
|
+
- gemfiles/rails_7.0_paper_trail_15.0_kaminari.gemfile
|
|
29
|
+
- gemfiles/rails_7.0_paper_trail_15.0_will_paginate.gemfile
|
|
30
|
+
- gemfiles/rails_7.1_paper_trail_15.0_kaminari.gemfile
|
|
31
|
+
- gemfiles/rails_7.1_paper_trail_15.0_will_paginate.gemfile
|
|
59
32
|
|
|
60
33
|
env:
|
|
61
|
-
BUNDLER_VERSION: 1.17.3
|
|
62
34
|
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
63
35
|
|
|
64
36
|
steps:
|
|
65
|
-
- uses: actions/checkout@
|
|
66
|
-
- uses:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: ruby/setup-ruby@v1
|
|
67
39
|
with:
|
|
68
40
|
ruby-version: ${{ matrix.ruby }}
|
|
69
|
-
|
|
70
|
-
with:
|
|
71
|
-
path: vendor/bundle
|
|
72
|
-
key: ${{ runner.os }}-${{ matrix.ruby}}-gems-${{ hashFiles('**/paper_trail_manager.gemspec') }}
|
|
73
|
-
restore-keys: |
|
|
74
|
-
${{ runner.os }}-${{ matrix.ruby }}-gems-
|
|
41
|
+
bundler-cache: true
|
|
75
42
|
- name: Install System Dependencies
|
|
76
43
|
run: |
|
|
77
44
|
sudo apt-get update
|
|
78
|
-
sudo apt-get install sqlite3 libsqlite3-dev
|
|
79
|
-
gem install bundler -v $BUNDLER_VERSION
|
|
45
|
+
sudo apt-get install -y sqlite3 libsqlite3-dev
|
|
80
46
|
- name: bundle install
|
|
81
47
|
run: |
|
|
82
48
|
bundle config path vendor/bundle
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.3.0
|
data/Appraisals
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
{
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'5.2.0' => %w[9.0 10.0],
|
|
8
|
-
'6.0.0' => %w[10.0]
|
|
4
|
+
'6.1' => %w[12.0],
|
|
5
|
+
'7.0' => %w[12.0 15.0],
|
|
6
|
+
'7.1' => %w[15.0]
|
|
9
7
|
}.each do |rails_version, paper_trail_versions|
|
|
10
8
|
paper_trail_versions.each do |paper_trail_version|
|
|
11
9
|
appraise "rails-#{rails_version}-paper_trail-#{paper_trail_version}-will-paginate" do
|
|
12
|
-
gem 'rails', "~> #{rails_version}"
|
|
13
|
-
gem '
|
|
14
|
-
gem 'sqlite3', rails_version == '6.0.0' ? '~> 1.4' : '~> 1.3.6'
|
|
10
|
+
gem 'rails', "~> #{rails_version}.0"
|
|
11
|
+
gem 'sqlite3', '~> 1.7'
|
|
15
12
|
gem 'paper_trail', "~> #{paper_trail_version}"
|
|
16
|
-
gem 'will_paginate', '~>
|
|
17
|
-
|
|
18
|
-
gem 'webpacker' if rails_version == '6.0.0'
|
|
13
|
+
gem 'will_paginate', '~> 4.0'
|
|
19
14
|
end
|
|
20
15
|
|
|
21
16
|
appraise "rails-#{rails_version}-paper_trail-#{paper_trail_version}-kaminari" do
|
|
22
|
-
gem 'rails', "~> #{rails_version}"
|
|
23
|
-
gem '
|
|
24
|
-
gem 'sqlite3', rails_version == '6.0.0' ? '~> 1.4' : '~> 1.3.6'
|
|
17
|
+
gem 'rails', "~> #{rails_version}.0"
|
|
18
|
+
gem 'sqlite3', '~> 1.7'
|
|
25
19
|
gem 'paper_trail', "~> #{paper_trail_version}"
|
|
26
|
-
gem 'kaminari', '>= 0
|
|
27
|
-
|
|
28
|
-
gem 'webpacker' if rails_version == '6.0.0'
|
|
20
|
+
gem 'kaminari', '>= 1.0'
|
|
29
21
|
end
|
|
30
22
|
end
|
|
31
23
|
end
|
data/CHANGES.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
Changes to `paper_trail_manager`
|
|
2
2
|
================================
|
|
3
3
|
|
|
4
|
+
* 0.8.0
|
|
5
|
+
* Fix `allow_show?` calling `allow_index_block` instead of `allow_show_block` — `allow_show_when` configuration was previously silently ignored (security fix)
|
|
6
|
+
* Fix gemspec `authors` field being overwritten by misplaced `email` assignment
|
|
7
|
+
* Fix `PER_PAGE` constant (50) not being used as default pagination
|
|
8
|
+
* Fix broken HTML structure in show view (nested `<tr>` tags) and index view (unwrapped `<td>`)
|
|
9
|
+
* Add date range filtering to changes index via `from` and `to` query parameters
|
|
10
|
+
* Add date filter UI with date inputs, filter button, and clear link
|
|
11
|
+
* Add authorization integration tests (unauthorized index/show/revert, non-existent records)
|
|
12
|
+
* Add unit tests for ChangesHelper methods (text_or_nil, changes_for, change_item_types, version_reify)
|
|
13
|
+
* Add specs for JSON and Atom response formats with filter coverage
|
|
14
|
+
* Add date range filter tests
|
|
15
|
+
* Drop support for Rails < 7.0
|
|
16
|
+
* Drop Rails 6.1 from CI matrix (incompatible with Ruby 3.1+)
|
|
17
|
+
* Fix `rails new` asset pipeline error in CI for Rails 7.0/7.1
|
|
18
|
+
* Fix `Psych::DisallowedClass` error on revert tests (Ruby 3.1+ YAML deserialization)
|
|
19
|
+
* Add support for Ruby 3.1, 3.2, and 3.3
|
|
20
|
+
* Add support for PaperTrail 12.x and 15.x
|
|
21
|
+
|
|
4
22
|
* 0.7.0
|
|
5
23
|
* Add support for Rails 5 and 6
|
|
6
24
|
* Add support for paper_trail 5.x – 10.x
|
data/README.md
CHANGED
|
@@ -1,109 +1,173 @@
|
|
|
1
|
-
[](http://travis-ci.org/fusion94/paper_trail_manager)
|
|
2
|
-
|
|
3
1
|
# PaperTrailManager
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
[](https://github.com/DamageLabs/paper_trail_manager/actions/workflows/test.yml)
|
|
4
|
+
[](https://rubygems.org/gems/paper_trail_manager)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://www.ruby-lang.org/)
|
|
7
|
+
[](https://rubyonrails.org/)
|
|
8
|
+
|
|
9
|
+
Browse, view, and revert changes to records in Ruby on Rails applications using the [paper_trail](https://github.com/paper-trail-gem/paper_trail) gem.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
- **Ruby** >= 3.1
|
|
14
|
+
- **Rails** >= 7.0, < 8.0
|
|
15
|
+
- **PaperTrail** >= 12.0
|
|
16
|
+
- A pagination library: [will_paginate](https://github.com/mislav/will_paginate) or [Kaminari](https://github.com/kaminari/kaminari)
|
|
8
17
|
|
|
9
18
|
## Installation
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
Add to your `Gemfile`:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
gem 'paper_trail_manager'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If you don't already use a pagination library, add one:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
gem 'kaminari'
|
|
30
|
+
# or
|
|
31
|
+
gem 'will_paginate'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Install:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
bundle install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Add the route to `config/routes.rb`:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
resources :changes, controller: 'paper_trail_manager/changes'
|
|
44
|
+
```
|
|
12
45
|
|
|
13
|
-
|
|
46
|
+
Restart your server and visit `/changes` to browse, view, and revert your changes.
|
|
14
47
|
|
|
15
|
-
|
|
48
|
+
## Configuration
|
|
16
49
|
|
|
17
|
-
|
|
50
|
+
Create an initializer (e.g. `config/initializers/paper_trail_manager.rb`) to customize behavior.
|
|
18
51
|
|
|
19
|
-
|
|
20
|
-
#or
|
|
21
|
-
gem 'will_paginate'
|
|
52
|
+
### Authorization
|
|
22
53
|
|
|
23
|
-
|
|
54
|
+
Control access to the index, show, and revert actions independently:
|
|
24
55
|
|
|
25
|
-
|
|
56
|
+
```ruby
|
|
57
|
+
# Control who can view the changes index
|
|
58
|
+
PaperTrailManager.allow_index_when do |controller|
|
|
59
|
+
controller.current_user.present?
|
|
60
|
+
end
|
|
26
61
|
|
|
27
|
-
|
|
62
|
+
# Control who can view individual change details (defaults to allow_index rules)
|
|
63
|
+
PaperTrailManager.allow_show_when do |controller, version|
|
|
64
|
+
controller.current_user&.admin? || version.whodunnit == controller.current_user&.id&.to_s
|
|
65
|
+
end
|
|
28
66
|
|
|
29
|
-
|
|
67
|
+
# Control who can revert changes
|
|
68
|
+
PaperTrailManager.allow_revert_when do |controller, version|
|
|
69
|
+
controller.current_user&.admin?
|
|
70
|
+
end
|
|
71
|
+
```
|
|
30
72
|
|
|
31
|
-
|
|
73
|
+
> **Note:** If you only call `allow_index_when`, the same block is used as the default for `allow_show_when`. Call `allow_show_when` separately to override show authorization independently.
|
|
32
74
|
|
|
33
|
-
|
|
75
|
+
### Whodunnit
|
|
34
76
|
|
|
35
|
-
|
|
77
|
+
Configure how to look up users referenced in PaperTrail's `whodunnit` column:
|
|
36
78
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
79
|
+
```ruby
|
|
80
|
+
PaperTrailManager.whodunnit_class = User
|
|
81
|
+
PaperTrailManager.whodunnit_name_method = :nicename # defaults to :name
|
|
82
|
+
```
|
|
40
83
|
|
|
41
|
-
|
|
84
|
+
### Item Names
|
|
42
85
|
|
|
43
|
-
|
|
44
|
-
controller.current_user and controller.current_user.admin?
|
|
45
|
-
end
|
|
86
|
+
Specify a method to identify items on the index page:
|
|
46
87
|
|
|
47
|
-
|
|
88
|
+
```ruby
|
|
89
|
+
PaperTrailManager.item_name_method = :nicename
|
|
90
|
+
```
|
|
48
91
|
|
|
49
|
-
|
|
50
|
-
PaperTrailManager.whodunnit_name_method = :nicename # defaults to :name
|
|
92
|
+
### User Links
|
|
51
93
|
|
|
52
|
-
|
|
94
|
+
Customize (or disable) the user path helper:
|
|
53
95
|
|
|
54
|
-
|
|
96
|
+
```ruby
|
|
97
|
+
PaperTrailManager.user_path_method = :admin_path # defaults to :user_path
|
|
98
|
+
PaperTrailManager.user_path_method = nil # no user link
|
|
99
|
+
```
|
|
55
100
|
|
|
56
|
-
|
|
101
|
+
### Pagination
|
|
57
102
|
|
|
58
|
-
|
|
59
|
-
PaperTrailManager.user_path_method = nil # no "show user" page in app
|
|
103
|
+
The index page defaults to 50 items per page. Override via query parameter:
|
|
60
104
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
105
|
+
```
|
|
106
|
+
/changes?per_page=25
|
|
107
|
+
```
|
|
64
108
|
|
|
65
|
-
|
|
66
|
-
PaperTrailManager.route_helpers = MyEngine::Engine.routes.url_helpers
|
|
109
|
+
### Engine Integration
|
|
67
110
|
|
|
68
|
-
|
|
111
|
+
When embedding PaperTrailManager inside another Rails engine:
|
|
69
112
|
|
|
70
|
-
|
|
113
|
+
```ruby
|
|
114
|
+
PaperTrailManager.base_controller = "MyEngine::ApplicationController"
|
|
115
|
+
PaperTrailManager.route_helpers = MyEngine::Engine.routes.url_helpers
|
|
116
|
+
PaperTrailManager.layout = 'my_engine/application'
|
|
117
|
+
```
|
|
71
118
|
|
|
72
119
|
## Development
|
|
73
120
|
|
|
74
121
|
Setup:
|
|
75
122
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
123
|
+
```sh
|
|
124
|
+
git clone https://github.com/DamageLabs/paper_trail_manager.git
|
|
125
|
+
cd paper_trail_manager
|
|
126
|
+
bundle install
|
|
127
|
+
```
|
|
79
128
|
|
|
80
129
|
Running tests:
|
|
81
130
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
131
|
+
```sh
|
|
132
|
+
appraisal rake
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The first run downloads gems for each Rails version in the test matrix, which may take a while.
|
|
136
|
+
|
|
137
|
+
### Test Matrix
|
|
138
|
+
|
|
139
|
+
Tests run against multiple combinations via [Appraisal](https://github.com/thoughtbot/appraisal):
|
|
140
|
+
|
|
141
|
+
| Rails | PaperTrail | Pagination |
|
|
142
|
+
|-------|-----------|------------|
|
|
143
|
+
| 7.0 | 12.0 | kaminari, will_paginate |
|
|
144
|
+
| 7.0 | 15.0 | kaminari, will_paginate |
|
|
145
|
+
| 7.1 | 15.0 | kaminari, will_paginate |
|
|
146
|
+
|
|
147
|
+
CI runs each combination across Ruby 3.1, 3.2, and 3.3 (18 jobs total).
|
|
148
|
+
|
|
149
|
+
### Adding Support for New Versions
|
|
150
|
+
|
|
151
|
+
1. Update the `Appraisals` file with new version combinations
|
|
152
|
+
2. Run `appraisal generate && appraisal install`
|
|
153
|
+
3. Fix any breaking changes
|
|
154
|
+
4. Submit a pull request
|
|
155
|
+
|
|
156
|
+
## Recent Changes (0.8.0)
|
|
157
|
+
|
|
158
|
+
- **Security fix:** `allow_show?` now correctly delegates to `allow_show_block` (was incorrectly using `allow_index_block`)
|
|
159
|
+
- **Bug fix:** Gemspec `authors` field was being overwritten by `email`
|
|
160
|
+
- **Bug fix:** `PER_PAGE` constant (50) now used as pagination default
|
|
161
|
+
- **CI:** Dropped Rails 6.1 (incompatible with Ruby 3.1+), fixed Psych deserialization, added asset pipeline skip
|
|
162
|
+
- **Tests:** Added unit tests for authorization block delegation
|
|
163
|
+
- Modernized for Ruby 3.1–3.3 and Rails 7.0–7.1
|
|
164
|
+
|
|
165
|
+
See [CHANGES.md](CHANGES.md) for full history.
|
|
102
166
|
|
|
103
167
|
## License
|
|
104
168
|
|
|
105
|
-
|
|
169
|
+
MIT — see [LICENSE.txt](LICENSE.txt) for details.
|
|
106
170
|
|
|
107
|
-
##
|
|
171
|
+
## History
|
|
108
172
|
|
|
109
|
-
This project was originally
|
|
173
|
+
This project was originally developed by [Igal Koshevoy](https://github.com/igal). Igal passed away on April 9th, 2013, and [Tony Guntharp](https://github.com/fusion94) took over maintenance of the project.
|
data/Rakefile
CHANGED
|
@@ -29,8 +29,10 @@ end
|
|
|
29
29
|
|
|
30
30
|
task :generate_spec_app do
|
|
31
31
|
sh 'rm -rf spec/dummy'
|
|
32
|
-
sh 'rails new spec/dummy --skip-bootsnap --skip-bundle
|
|
33
|
-
--skip-git --skip-action-mailer --skip-puma --skip-test
|
|
34
|
-
--skip-spring --skip-
|
|
32
|
+
sh 'rails new spec/dummy --skip-bootsnap --skip-bundle \
|
|
33
|
+
--skip-git --skip-action-mailer --skip-puma --skip-test \
|
|
34
|
+
--skip-spring --skip-hotwire --skip-jbuilder \
|
|
35
|
+
--skip-action-mailbox --skip-action-text --skip-active-storage \
|
|
36
|
+
--skip-asset-pipeline \
|
|
35
37
|
--template=spec/app_template.rb'
|
|
36
38
|
end
|
|
@@ -23,12 +23,18 @@ class PaperTrailManager
|
|
|
23
23
|
@versions = @versions.where(item_type: params[:type]) if params[:type]
|
|
24
24
|
@versions = @versions.where(item_id: params[:id]) if params[:id]
|
|
25
25
|
|
|
26
|
+
# Date range filtering
|
|
27
|
+
@from = parse_date(params[:from])
|
|
28
|
+
@to = parse_date(params[:to])
|
|
29
|
+
@versions = @versions.where('created_at >= ?', @from.beginning_of_day) if @from
|
|
30
|
+
@versions = @versions.where('created_at <= ?', @to.end_of_day) if @to
|
|
31
|
+
|
|
26
32
|
# Ensure pagination parameters have sensible values
|
|
27
33
|
@page = params[:page].to_i
|
|
28
34
|
@page = nil if @page.zero?
|
|
29
35
|
|
|
30
36
|
@per_page = params[:per_page].to_i
|
|
31
|
-
@per_page =
|
|
37
|
+
@per_page = PER_PAGE if @per_page.zero?
|
|
32
38
|
|
|
33
39
|
@versions = if defined?(WillPaginate)
|
|
34
40
|
@versions.paginate(page: @page, per_page: @per_page)
|
|
@@ -127,5 +133,14 @@ class PaperTrailManager
|
|
|
127
133
|
PaperTrailManager.allow_revert?(self, version)
|
|
128
134
|
end
|
|
129
135
|
helper_method :change_revert_allowed?
|
|
136
|
+
|
|
137
|
+
# Parse a date string, returning nil for invalid/missing values
|
|
138
|
+
def parse_date(value)
|
|
139
|
+
return nil if value.blank?
|
|
140
|
+
|
|
141
|
+
Date.parse(value)
|
|
142
|
+
rescue Date::Error, ArgumentError
|
|
143
|
+
nil
|
|
144
|
+
end
|
|
130
145
|
end
|
|
131
146
|
end
|
|
@@ -59,9 +59,9 @@ class PaperTrailManager
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def change_item_types
|
|
62
|
-
ActiveRecord::Base.
|
|
62
|
+
ActiveRecord::Base.descendants.select do |klass|
|
|
63
63
|
klass.include?(PaperTrail::Model::InstanceMethods)
|
|
64
|
-
end.map(&:to_s)
|
|
64
|
+
end.map(&:to_s).sort
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# Returns HTML link for the item stored in the version, e.g. a link to a Company record stored in the version.
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<% end %>
|
|
21
21
|
<% end %>
|
|
22
22
|
<% if change_revert_allowed?(version) %>
|
|
23
|
-
<%=
|
|
23
|
+
<%= button_to 'Roll back', change_path(version), method: :put, class: 'rollback', form: { data: { turbo_confirm: 'Are you sure?' } } %>
|
|
24
24
|
<% end %>
|
|
25
25
|
</p>
|
|
26
26
|
<% if version.event == 'update' or version.event == 'create' %>
|
|
@@ -1,35 +1,48 @@
|
|
|
1
1
|
<h1>Changes</h1>
|
|
2
2
|
|
|
3
|
-
<p class='changes_feed'><%= link_to 'Changes feed', changes_path(:format => 'atom') %></p>
|
|
4
|
-
|
|
5
3
|
<p>
|
|
6
4
|
Show:
|
|
7
|
-
<%= ([link_to('All', changes_path)] + change_item_types.map { |type| link_to(type.pluralize, changes_path(:
|
|
5
|
+
<%= ([link_to('All', changes_path)] + change_item_types.map { |type| link_to(type.pluralize, changes_path(type: type)) }).join(' | ').html_safe %>
|
|
8
6
|
</p>
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
8
|
+
<%= form_tag changes_path, method: :get, class: 'changes_date_filter' do %>
|
|
9
|
+
<%= hidden_field_tag :type, params[:type] if params[:type] %>
|
|
10
|
+
<%= hidden_field_tag :id, params[:id] if params[:id] %>
|
|
11
|
+
<label for="from">From:</label>
|
|
12
|
+
<%= date_field_tag :from, params[:from], id: 'from' %>
|
|
13
|
+
<label for="to">To:</label>
|
|
14
|
+
<%= date_field_tag :to, params[:to], id: 'to' %>
|
|
15
|
+
<%= submit_tag 'Filter', name: nil %>
|
|
16
|
+
<% if params[:from].present? || params[:to].present? %>
|
|
17
|
+
<%= link_to 'Clear', changes_path(type: params[:type], id: params[:id]), class: 'clear_filter' %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<div class="table-responsive">
|
|
21
|
+
<table class='changes_table table table-bordered'>
|
|
22
|
+
<tfoot>
|
|
23
|
+
<tr>
|
|
24
|
+
<td colspan='2'>
|
|
25
|
+
<%= paginate @versions %>
|
|
26
|
+
</td>
|
|
27
|
+
</tr>
|
|
28
|
+
</tfoot>
|
|
29
|
+
<thead>
|
|
30
|
+
<tr class='changes_header'>
|
|
31
|
+
<th class='change_time'>Time</th>
|
|
32
|
+
<th class='change_details'>Attribute with previous and current values</th>
|
|
33
|
+
</tr>
|
|
34
|
+
</thead>
|
|
35
|
+
<tbody>
|
|
36
|
+
<% if @versions.any? %>
|
|
37
|
+
<% @versions.each do |version| %>
|
|
38
|
+
<% next unless change_show_allowed?(version) %>
|
|
39
|
+
<%= render partial: 'version', object: version %>
|
|
40
|
+
<% end %>
|
|
41
|
+
<% else %>
|
|
42
|
+
<tr>
|
|
43
|
+
<td colspan='2'> — No changes found — </td>
|
|
44
|
+
</tr>
|
|
29
45
|
<% end %>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</tbody>
|
|
34
|
-
</table>
|
|
35
|
-
|
|
46
|
+
</tbody>
|
|
47
|
+
</table>
|
|
48
|
+
</div>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<h1>Change <%= @version.id %></h1>
|
|
2
2
|
|
|
3
3
|
<table class='changes_table'>
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
<thead>
|
|
5
|
+
<tr class='changes_header'>
|
|
6
|
+
<th class='change_time'>Time</th>
|
|
7
|
+
<th class='change_details'>Attribute with previous and current values</th>
|
|
8
|
+
</tr>
|
|
9
|
+
</thead>
|
|
10
|
+
<tbody>
|
|
11
|
+
<%= render partial: 'version', object: @version %>
|
|
12
|
+
</tbody>
|
|
9
13
|
</table>
|
|
10
|
-
|