whodunit 0.4.0 → 0.4.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: b118c7a04ca24e4cfd6aa759e57b5c92e51be74f87b35a89ae6e5654f3a56051
4
- data.tar.gz: db5c8c236bd170f7ce42b14682c3c44c6eaaae2dc125b6c8e9cdf9ef7a9a9596
3
+ metadata.gz: ec3f89bd20ea577eb0a740137c86a7927500ccd189e9d9375d18b21c0b36ffdc
4
+ data.tar.gz: 20586d959bc0d25a47319f615f333021d1ebbec331d865c6a18400987f24ef39
5
5
  SHA512:
6
- metadata.gz: 4324dc93c29055aaa6dcc02b1999484d8108a4212eb8474185d5c0dee47e6d99fc88ed938d344f17bf75747a2eb5023ef2d6295d5308d9c838fd9b2f00c349dd
7
- data.tar.gz: 6f31152d504e0b80a81992c3f62f190ac9de4aba73d0a964e24c116052ea5093629b6182eff58d6c9f811c2b3bec95b5385f49ef45429cc8f11d66a6d190d988
6
+ metadata.gz: 5cca573bee0c6d0313d5adf4079e18996d4bc5ecf354b7de39f77e9537b078c67d6122d4a2a7c8c3314ec9da44f40a5ec262a573c06e12b092f86935a951b327
7
+ data.tar.gz: 810bd48aaf36a9605802c62d8f6616d0d68eb63b78a2f92c955c0f06b0cc609f0f6c729274bfc33d5caf42e8263ce8a49d4aa253480db7103dd0c0ea756ce5e1
data/.rubocop.yml CHANGED
@@ -35,6 +35,7 @@ Metrics/BlockLength:
35
35
 
36
36
  # Allow longer methods in specs and configuration
37
37
  Metrics/MethodLength:
38
+ Max: 15
38
39
  Exclude:
39
40
  - 'spec/**/*'
40
41
 
data/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.1] - 2026-06-01
9
+
10
+ ### Fixed
11
+
12
+ - Fixed `Whodunit::Stampable` when included on an abstract ActiveRecord base class, such as `ApplicationRecord`. Association setup and model registration are now deferred to concrete subclasses.
13
+ - Preserved existing `inherited` hooks by prepending an internal hook instead of replacing `self.inherited`.
14
+ - Supported multi-level abstract inheritance, such as `ApplicationRecord -> TenantRecord -> Post`, without registering abstract classes.
15
+
16
+ ### Added
17
+
18
+ - Added RSpec regression coverage for abstract-base inclusion, inherited-hook preservation, abstract subclass exclusion, concrete subclass registration, multi-level abstract inheritance, and inherited callback stamping.
19
+
8
20
  ## [0.4.0] - 2025-05-20
9
21
 
10
22
  ### Breaking Changes
@@ -50,12 +50,16 @@ module Whodunit
50
50
  before_destroy :set_whodunit_deleter, if: :deleter_column?
51
51
  before_update :set_whodunit_deleter, if: :being_soft_deleted?
52
52
 
53
- # Set up associations - call on the class
54
- setup_whodunit_associations
55
-
56
- # Register this model for reverse association setup
57
- # This happens immediately, but the check for enabled status is done in register_model
58
- Whodunit.register_model(self)
53
+ if abstract_class?
54
+ install_whodunit_inherited_hook
55
+ else
56
+ # Set up associations - call on the including concrete class.
57
+ setup_whodunit_associations
58
+
59
+ # Register this including model for reverse association setup.
60
+ # This happens immediately, but the check for enabled status is done in register_model.
61
+ Whodunit.register_model(self)
62
+ end
59
63
  end
60
64
 
61
65
  class_methods do # rubocop:disable Metrics/BlockLength
@@ -144,6 +148,43 @@ module Whodunit
144
148
 
145
149
  private
146
150
 
151
+ # Install an inherited hook when Stampable is included on an abstract ActiveRecord
152
+ # base class, such as ApplicationRecord. Associations require concrete table
153
+ # metadata, so setup must be deferred until concrete subclasses are defined.
154
+ #
155
+ # The hook is prepended instead of assigned with `def self.inherited` so existing
156
+ # inherited hooks on the application base class remain intact. When the subclass
157
+ # is also abstract, the same hook is propagated so multi-level abstract
158
+ # inheritance is supported.
159
+ #
160
+ # @return [void]
161
+ # @api private
162
+ def install_whodunit_inherited_hook
163
+ return if instance_variable_defined?(:@whodunit_inherited_hook_installed) &&
164
+ @whodunit_inherited_hook_installed
165
+
166
+ inherited_hook = Module.new do
167
+ def inherited(subclass)
168
+ super
169
+
170
+ subclass.send(:install_whodunit_inherited_hook)
171
+
172
+ return if subclass.abstract_class?
173
+ return if subclass.name.nil?
174
+
175
+ subclass.send(:setup_whodunit_associations)
176
+ Whodunit.register_model(subclass)
177
+ end
178
+ end
179
+
180
+ singleton_class.prepend(inherited_hook)
181
+ @whodunit_inherited_hook_installed = true
182
+ end
183
+
184
+ # Set up associations for concrete ActiveRecord models.
185
+ #
186
+ # @return [void]
187
+ # @api private
147
188
  def setup_whodunit_associations
148
189
  return if abstract_class?
149
190
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Whodunit
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whodunit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken C. Demanawa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-20 00:00:00.000000000 Z
11
+ date: 2026-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord