well_formed-paper_trail 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9aa0be2c5bdb3f7c9f04d9e81ac7481fe76dd4ecb65b87aa559fb3a87ac666ba
4
+ data.tar.gz: 578dcf5c3f11f0cfd0b5c3c458710944d2250b7b8185c990649239680c5d1af8
5
+ SHA512:
6
+ metadata.gz: 74a4f2bbe4f5a581a15a72e56bb195c84cb473fe2f8d8c67bc8b1c12d0c58017dca55959e0a84f040acafd96c0aafe57075bfd5adddb2eb4a598f589cb89a7d4
7
+ data.tar.gz: 26785c4bd0b2029fd0f82ec64c6c1389af96b616194c001a2231018bab7dc99fa60b8d40659d217fbf6d5b03bca8ae26132182a5025d6c0a6a13cf54a8187405
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # well_formed-paper_trail
2
+
3
+ [PaperTrail](https://github.com/paper-trail-gem/paper_trail) versioning integration for [WellFormed](https://github.com/bmorrall/well_formed) form objects.
4
+
5
+ Automatically sets `PaperTrail.request.whodunnit` to the form's `user` around every `save` and `perform`, so version records are attributed to the correct user without any controller wiring.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ bundle add well_formed-paper_trail
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Require the gem in your application:
16
+
17
+ ```ruby
18
+ require "well_formed-paper_trail"
19
+ ```
20
+
21
+ `WellFormed::PaperTrail` is automatically included into all WellFormed forms — no `include` required. With PaperTrail configured on your models, versions are immediately attributed to the form's `user`:
22
+
23
+ ```ruby
24
+ class UpdateArticleForm < WellFormed::ResourceForm
25
+ resource_alias :article
26
+
27
+ attribute :title, :string
28
+ attribute :body, :string
29
+
30
+ validates :title, presence: true
31
+ end
32
+
33
+ form = UpdateArticleForm.new(article, current_user, article_params)
34
+ form.save
35
+ # => PaperTrail::Version created with whodunnit: current_user.id.to_s
36
+ ```
37
+
38
+ Works for `ActionForm` too — any model changes made inside `perform` are attributed correctly:
39
+
40
+ ```ruby
41
+ class PublishArticleForm < WellFormed::ActionForm
42
+ resource_alias :article
43
+
44
+ def perform
45
+ article.publish! # triggers a PaperTrail version attributed to user
46
+ end
47
+ end
48
+ ```
49
+
50
+ ### Custom whodunnit
51
+
52
+ By default, `whodunnit` is set to `user&.id&.to_s`. There are two ways to override this.
53
+
54
+ #### Global default
55
+
56
+ Set a global proc in an initializer. It receives the form's `user` as its argument:
57
+
58
+ ```ruby
59
+ # config/initializers/well_formed_paper_trail.rb
60
+ WellFormed::PaperTrail.whodunnit = ->(user) { user&.email }
61
+ ```
62
+
63
+ #### Per-form override
64
+
65
+ Use `paper_trail_whodunnit` to override on a specific form class. The block is evaluated in the context of the form instance, so all form attributes and helpers (including `user`) are available:
66
+
67
+ ```ruby
68
+ class UpdateArticleForm < WellFormed::ResourceForm
69
+ paper_trail_whodunnit { user.email }
70
+ end
71
+ ```
72
+
73
+ ```ruby
74
+ class AdminUpdateForm < WellFormed::ResourceForm
75
+ paper_trail_whodunnit { "admin:#{user.id}" }
76
+ end
77
+ ```
78
+
79
+ The per-form macro takes precedence over the global config. It is also inherited by subclasses and can be overridden per subclass:
80
+
81
+ ```ruby
82
+ class BaseForm < WellFormed::ResourceForm
83
+ paper_trail_whodunnit { user.email }
84
+ end
85
+
86
+ class AuditedForm < BaseForm
87
+ paper_trail_whodunnit { "#{user.role}:#{user.id}" } # overrides parent
88
+ end
89
+ ```
90
+
91
+ The priority order is: **per-form macro → global config → `user&.id&.to_s`**.
92
+
93
+ ## API
94
+
95
+ | Method | Description |
96
+ |--------|-------------|
97
+ | `WellFormed::PaperTrail.whodunnit = ->(user) { ... }` | Global default — proc receives `user`, return value used as `whodunnit` |
98
+ | `paper_trail_whodunnit { ... }` | Per-form macro — block evaluated on the form instance, takes precedence over global config. Inherits from superclass. |
99
+
100
+ ## How it works
101
+
102
+ `whodunnit` is set via `PaperTrail.request(whodunnit:) { ... }` inside an `around_save` callback (for `ResourceForm` and `Struct`) or an `around_perform` callback (for `ActionForm`). This is the thread-safe, block-scoped API recommended by PaperTrail — the previous `whodunnit` value is always restored after the block exits, even if an exception is raised.
103
+
104
+ ## License
105
+
106
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new(:rubocop)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WellFormed
4
+ module PaperTrail
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WellFormed
4
+ module PaperTrail
5
+ @whodunnit = nil
6
+
7
+ class << self
8
+ # Global default whodunnit proc, used when no per-form +paper_trail_whodunnit+ is set.
9
+ # The proc receives the form's +user+ as its argument.
10
+ #
11
+ # WellFormed::PaperTrail.whodunnit = ->(user) { user&.email }
12
+ #
13
+ attr_accessor :whodunnit
14
+ end
15
+
16
+ def self.included(base)
17
+ base.extend(ClassMethods)
18
+ base.set_callback(:save, :around, :_with_paper_trail) if base.respond_to?(:_save_callbacks)
19
+ base.set_callback(:perform, :around, :_with_paper_trail) if base.respond_to?(:_perform_callbacks)
20
+ end
21
+
22
+ module ClassMethods
23
+ # Override the whodunnit value set on PaperTrail.request during save/perform.
24
+ # The block is evaluated in the context of the form instance, so form attributes
25
+ # and helpers (including +user+) are available.
26
+ #
27
+ # paper_trail_whodunnit { user.email }
28
+ # paper_trail_whodunnit { "admin:#{user.id}" }
29
+ #
30
+ # Defaults to +user&.id&.to_s+ when not set.
31
+ def paper_trail_whodunnit(&block)
32
+ @_paper_trail_whodunnit = block
33
+ end
34
+
35
+ def _paper_trail_whodunnit_proc
36
+ return @_paper_trail_whodunnit if defined?(@_paper_trail_whodunnit)
37
+
38
+ superclass._paper_trail_whodunnit_proc if superclass.respond_to?(:_paper_trail_whodunnit_proc)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def _with_paper_trail
45
+ whodunnit = if (proc = self.class._paper_trail_whodunnit_proc)
46
+ instance_exec(&proc)
47
+ elsif (global = WellFormed::PaperTrail.whodunnit)
48
+ global.call(user)
49
+ else
50
+ user&.id&.to_s
51
+ end
52
+ ::PaperTrail.request(whodunnit: whodunnit) { yield }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "well_formed"
4
+ require "paper_trail"
5
+ require_relative "well_formed/paper_trail/version"
6
+ require_relative "well_formed/paper_trail"
7
+
8
+ WellFormed::WithUser.register_extension(WellFormed::PaperTrail)
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: well_formed-paper_trail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Morrall
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: well_formed
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 0.1.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 0.1.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: paper_trail
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '12.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '12.0'
40
+ email:
41
+ - bemo56@hotmail.com
42
+ executables: []
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - ".rspec"
47
+ - README.md
48
+ - Rakefile
49
+ - lib/well_formed-paper_trail.rb
50
+ - lib/well_formed/paper_trail.rb
51
+ - lib/well_formed/paper_trail/version.rb
52
+ homepage: https://github.com/bmorrall/well_formed
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 3.1.0
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.6.9
71
+ specification_version: 4
72
+ summary: PaperTrail versioning integration for well_formed
73
+ test_files: []