paper_trail-actor 0.5.0 → 0.5.1

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
  SHA256:
3
- metadata.gz: 7b84892ec641d12e2f30f9779c934369db0ff3b3246cc6c12837f3750a704392
4
- data.tar.gz: 6d2dcde8f48e153acf1680c0f9dc278c2a5ed696dda0341557d0f104f12e5dbb
3
+ metadata.gz: 8d8d84d52637e0114f5ab6c64b3caf0d10b2a94d6049d1e4c1ec0826d4dd94f4
4
+ data.tar.gz: fdabf9efe06ee201f706b17fc47fc75ffe590c57657c479b6b4bb1a26428eb94
5
5
  SHA512:
6
- metadata.gz: 0cdefc8cb362df6ae343b23d60ff02ba28a3ebded2cc51f4a7e292cf70587b6a826074e0ed2a3554c5ff73f79893966b84314209247b509f9681153f818b45ff
7
- data.tar.gz: 8a50a20d5d6183cd6d0871ac24f3c84a6461339ec08fd1aacbd78e95ae0a6a207601720161d268288e170605df012aae47f4cb05533525ae0e39f462583e4793
6
+ metadata.gz: 50b13f56e781102f2c2da25054ea6530feff8d544a8320bc912157f4cb639f9a559ee6edc2166f58295aac8e7f7c716f06ea8f1abddc1fcf873a92f1e17ab3fd
7
+ data.tar.gz: ceec6f0626b24475afb00c413607491cb9456bab684a4ad835dc77798fbb3cf910a007c97e51ce5eb884dc176a2d03eb8828849704e5f5b3e342d5a6c054b8c2
data/CHANGELOG.md CHANGED
@@ -70,3 +70,17 @@
70
70
 
71
71
  - [#10](https://github.com/tttffff/paper_trail-actor/pull/10) Allow other object types.
72
72
  Can now use any object that implements globalid, not just ActiveRecord objects.
73
+
74
+ ## [0.5.1] - 2025-11-15
75
+
76
+ ### Breaking Changes
77
+
78
+ - None
79
+
80
+ ### Added
81
+
82
+ - None
83
+
84
+ ### Fixed
85
+
86
+ - Explicitly set required ruby version.
data/README.md CHANGED
@@ -1,26 +1,41 @@
1
1
  # PaperTrail-Actor
2
2
 
3
- This gem is an extension for [PaperTrail](https://github.com/paper-trail-gem/paper_trail) that allows you to set an `ActiveRecord` object as the "whodunnit" field. This enhancement provides more granular tracking of who made changes, making it easier to trace modifications in your application.
3
+ Track changes in your Rails application with precision. PaperTrail-Actor extends [PaperTrail](https://github.com/paper-trail-gem/paper_trail) to store full ActiveRecord objects (not just IDs) as the actor responsible for changes.
4
4
 
5
- ## Features
5
+ **Problem it solves:** When both `Admin` and `User` models can modify records, storing only an ID makes it impossible to know which model type made the change. PaperTrail-Actor stores GlobalIDs to uniquely identify actors across different model types.
6
+
7
+ ## Table of Contents
6
8
 
7
- - **Set an ActiveRecord Object for Whodunnit:** Use an `ActiveRecord` object to track who made changes.
8
- - **Return the ActiveRecord Object:** The method `#actor` can be used to get the object responsible for changes.
9
- - **Coexistence with Existing Versions:** Works seamlessly alongside existing PaperTrail versions, regardless of when they were created.
9
+ - [Features](#features)
10
+ - [Requirements](#requirements)
11
+ - [Installation](#installation)
12
+ - [Usage](#usage)
13
+ - [Basic Setup](#basic-setup)
14
+ - [Supported Object Types](#supported-object-types)
15
+ - [Controller Integration](#controller-integration)
16
+ - [Migrating Existing Data](#migrating-existing-data)
17
+ - [How It Works](#how-it-works)
18
+
19
+ ## Features
10
20
 
11
- ## How it works
21
+ - **Store any ActiveRecord object** as the actor who made changes
22
+ - **Retrieve the full object** with a simple `#actor` method
23
+ - **Backward compatible** with existing PaperTrail versions
24
+ - **Flexible** - works with strings, unpersisted records, and non-ActiveRecord objects
12
25
 
13
- This gem works by storing the [globalid](https://github.com/rails/globalid) to the whodunnit field of PaperTrail version tables. This allows you to add different object types to the whodunnit field, know exactly which object is responsible, and retrive that object with ease.
26
+ ## Requirements
14
27
 
15
- For example, if you have both `Admin` objects and `User` objects that are capable of making changes, this gem ensures that you can clearly identify who made the change instead of using purely an ID and not knowing if it was for an `Admin` or a `User`
28
+ - Ruby 2.7+
29
+ - Rails 6.0+
30
+ - PaperTrail 11.0+
16
31
 
17
32
  ## Installation
18
33
 
19
- 1. Add `paper_trail-actor` to your Gemfile:
34
+ 1. Add to your Gemfile:
20
35
  ```ruby
21
36
  gem "paper_trail-actor"
22
37
  ```
23
- 2. Run the following command:
38
+ 2. Install the gem:
24
39
  ```sh
25
40
  bundle install
26
41
  ```
@@ -29,95 +44,139 @@ For example, if you have both `Admin` objects and `User` objects that are capabl
29
44
 
30
45
  ### Basic Setup
31
46
 
32
- To use this gem, you first need to set a user (or any `ActiveRecord` object) to the `whodunnit` field.
47
+ Set any ActiveRecord object as the actor responsible for changes:
33
48
 
34
49
  ```ruby
35
- product = Product.find(42)
36
50
  admin = Admin.find(1)
37
-
38
51
  PaperTrail.request.whodunnit = admin
39
- PaperTrail.request.whodunnit # "gid://app/Admin/1"
40
- PaperTrail.request.actor # Returns the `Admin` object with id 1
41
- ```
42
52
 
43
- When you update the product, PaperTrail will remember who made the change:
44
-
45
- ```ruby
46
- product.update(name: "Ice cream")
47
- product.versions.last.whodunnit # "gid://app/Admin/1"
48
- product.versions.last.actor # Returns the `Admin` object with id 1
53
+ # Now all changes will be attributed to this admin
54
+ # See Supported Object Types section below for detailed examples
49
55
  ```
50
56
 
51
- ### Flexible Whodunnit
57
+ ### Supported Object Types
52
58
 
53
- The gem is designed to be flexible. You can set `whodunnit` with various types of objects:
59
+ The gem handles various object types gracefully:
54
60
 
55
- - **Strings:**
56
- ```ruby
57
- PaperTrail.request.whodunnit = "Alex the admin" # "Alex the admin"
58
- ```
61
+ **Persisted ActiveRecord objects:**
62
+ ```ruby
63
+ admin = Admin.find(1)
64
+ product = Product.find(42)
59
65
 
60
- - **New/unpersisted ActiveRecord Objects:**
61
- ```ruby
62
- PaperTrail.request.whodunnit = Admin.new # Sets the string representation of the admin
63
- ```
66
+ PaperTrail.request.whodunnit = admin
67
+ PaperTrail.request.whodunnit # => "gid://app/Admin/1"
68
+ PaperTrail.request.actor # => #<Admin id: 1>
64
69
 
65
- - **Non-ActiveRecord Objects:**
66
- ```ruby
67
- class Job
68
- def to_s
69
- "A job in the system"
70
- end
71
- end
70
+ # Make changes - PaperTrail will track the actor
71
+ product.update(name: "Ice cream")
72
+ product.versions.last.whodunnit # => "gid://app/Admin/1"
73
+ product.versions.last.actor # => #<Admin id: 1>
74
+ ```
72
75
 
73
- PaperTrail.request.whodunnit = Job.new # "A job in the system"
74
- ```
76
+ **Strings:**
77
+ ```ruby
78
+ PaperTrail.request.whodunnit = "Alex the admin"
79
+ PaperTrail.request.whodunnit # => "Alex the admin"
80
+ PaperTrail.request.actor # => "Alex the admin"
81
+ ```
75
82
 
76
- When you update the product, PaperTrail will store the string for who made the change:
83
+ **New/unpersisted ActiveRecord objects:**
84
+ ```ruby
85
+ PaperTrail.request.whodunnit = Admin.new(name: "New Admin")
86
+ # Cannot get a globalid for an unpersisted object. So we use the `#to_s` for the object.
87
+ PaperTrail.request.whodunnit # => "#<Admin:0x00007f8e8c0a0b80>"
88
+ PaperTrail.request.actor # => "#<Admin:0x00007f8e8c0a0b80>"
89
+ ```
77
90
 
91
+ **Non-ActiveRecord objects:**
78
92
  ```ruby
79
- product.update(name: "Ice cream")
80
- product.versions.last.whodunnit # "A job in the system"
81
- product.versions.last.actor # "A job in the system"
93
+ class BackgroundJob
94
+ def to_s
95
+ "BackgroundJob-#{object_id}"
96
+ end
97
+ end
98
+
99
+ PaperTrail.request.whodunnit = BackgroundJob.new
100
+ PaperTrail.request.whodunnit # => "BackgroundJob-12345"
101
+ PaperTrail.request.actor # => "BackgroundJob-12345"
82
102
  ```
83
103
 
84
- ### Updating Existing Versions
104
+ ### Controller Integration
85
105
 
86
- If you have existing PaperTrail versions and need to update them, you can do so by:
106
+ Set the actor automatically in your controllers using PaperTrail's built-in callback:
87
107
 
88
108
  ```ruby
89
- first_product_version = product.versions.first
90
- admin_id = first_product_version.actor # For example, "1"
91
- admin = Admin.find_by(id: admin_id)
92
-
93
- if admin.present?
94
- first_product_version.whodunnit = admin
95
- first_product_version.save
109
+ class ApplicationController < ActionController::Base
110
+ before_action :set_paper_trail_whodunnit
96
111
  end
97
112
  ```
98
113
 
99
- ### Setting whodunnit with a controller callback
114
+ If your controller has a `#current_user` method, PaperTrail-Actor will automatically use it and attribute all changes within the request cycle to that user.
100
115
 
101
- You can set the user for PaperTrail in the same way that the [PaperTrail documentation states](https://github.com/paper-trail-gem/paper_trail#setting-whodunnit-with-a-controller-callback).
116
+ ```ruby
117
+ # In your CRUD actions
118
+ def update
119
+ # Nothing else required here to attribute the user as the actor.
120
+ @product.update(product_params)
121
+ @product.versions.last.actor # => #<User id: 42> (full User object)
122
+ end
123
+ ```
102
124
 
103
- However, setting this to an ActiveRecord object now records the globalid. It also allows the object to be retrived from created PaperTrail versions with the `#actor` method.
125
+ **Before PaperTrail-Actor:**
126
+ ```ruby
127
+ # whodunnit was just a string like "42"
128
+ version.whodunnit # => "42"
129
+ # You couldn't tell if this was User 42 or Admin 42
130
+ ```
104
131
 
105
- If your controller has a `#current_user` method, PaperTrail-Actor will assign the globalid of the current user to whodunnit. If your controller doesn't have a `#current_user`, or if the current user is `nil`, then whodunnit will not be set.
132
+ **After PaperTrail-Actor:**
133
+ ```ruby
134
+ # whodunnit stores the full GlobalID
135
+ version.whodunnit # => "gid://app/User/42"
136
+ version.actor # => #<User id: 42>
137
+ # Now you know exactly who to attribute the change to
138
+ ```
106
139
 
107
- You may want set `#user_for_paper_trail` to call a different method to find out who is responsible. To do so, override the `#user_for_paper_trail` method in your controller:
140
+ Override `#user_for_paper_trail` to customize the actor selection logic:
108
141
 
109
142
  ```ruby
110
143
  class ApplicationController < ActionController::Base
111
144
  before_action :set_paper_trail_whodunnit
112
145
 
146
+ private
147
+
113
148
  def user_for_paper_trail
114
149
  logged_in? ? current_admin : "Public user"
115
150
  end
116
151
  end
117
152
  ```
118
153
 
119
- ## Contributing
154
+ ### Migrating Existing Data
155
+
156
+ **When to migrate:** Install PaperTrail-Actor on an existing app with PaperTrail data.
157
+
158
+ **How to migrate:** Convert existing string IDs to GlobalIDs:
159
+
160
+ ```ruby
161
+ # Find a version with a plain ID
162
+ version = product.versions.first
163
+ # => #<PaperTrail::Version id: 1, whodunnit: "123">
164
+
165
+ # Convert to GlobalID
166
+ admin = Admin.find_by(id: version.whodunnit)
167
+ if admin.present?
168
+ version.update!(whodunnit: admin)
169
+ version.whodunnit # => "gid://app/Admin/123"
170
+ version.actor # => #<Admin id: 123>
171
+ end
172
+ ```
173
+
174
+ ## How It Works
175
+
176
+ PaperTrail-Actor serializes ActiveRecord objects using [GlobalID](https://github.com/rails/globalid) and stores them in PaperTrail's `whodunnit` column. This enables:
177
+
178
+ - **Type-safe actor identification**: `gid://app/Admin/1` vs `gid://app/User/1`
179
+ - **Automatic deserialization**: Call `#actor` to get back the original ActiveRecord object
180
+ - **Graceful fallback**: Non-ActiveRecord objects are stored as strings
120
181
 
121
- 1. Please add tests for PRs that are created.
122
- 2. Run the tests `bundle exec rake spec` to ensure that they all pass.
123
- 3. Lint the code `bundle exec rake standard:fix` to ensure that convention is maintained.
182
+ For example, if you have both `Admin` and `User` models that can make changes, this gem ensures you can clearly identify who made the change instead of using only an ID without knowing the model type.
@@ -1,3 +1,3 @@
1
1
  module PaperTrailActor
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail-actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - tttffff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-29 00:00:00.000000000 Z
11
+ date: 2025-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paper_trail
@@ -108,8 +108,9 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: An extension to PaperTrail. Using this gem, you can fetch the ActiveRecord
112
- object that was responsible for changes
111
+ description: An extension to PaperTrail that allows you to retrieve the ActiveRecord
112
+ object (actor) that was responsible for creating or modifying records, enabling
113
+ better audit trails and change attribution.
113
114
  email:
114
115
  - tristanfellows@icloud.com
115
116
  executables: []
@@ -141,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
142
  requirements:
142
143
  - - ">="
143
144
  - !ruby/object:Gem::Version
144
- version: '0'
145
+ version: '2.7'
145
146
  required_rubygems_version: !ruby/object:Gem::Requirement
146
147
  requirements:
147
148
  - - ">="
@@ -151,6 +152,5 @@ requirements: []
151
152
  rubygems_version: 3.5.22
152
153
  signing_key:
153
154
  specification_version: 4
154
- summary: An extension to PaperTrail. Using this gem, you can fetch the ActiveRecord
155
- object that was responsible for changes
155
+ summary: Fetch the ActiveRecord object responsible for PaperTrail changes
156
156
  test_files: []