acts_as_trackable 0.4.2 → 0.4.4

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: ba1f9f6e084d46878fcc2c2a9449c44599571ded79f960778109215bd2e6e974
4
- data.tar.gz: d5e4eb2b78cd9b4e72887e71cc074e6ebcf7864a1650c409aef1545c3c5fa2cf
3
+ metadata.gz: 2a7d07c3e789702cf675c58c1228f05eada87d244a6026eaf2fdc0da02dc8252
4
+ data.tar.gz: c2e5d21b078655af1c99e3eb2aad715097358d56b270e3966b6d837d74b70585
5
5
  SHA512:
6
- metadata.gz: '08711912e524e757253b670f3dc7f47c412c8df79f01339b3a7c7b91e47b89a92226134a9d88a1e5fd35e15b5a38a63fbb67511532a348358682327348dcf3e5'
7
- data.tar.gz: ee9f1b3365713c4eadd7fdc7c4fd690e18c7a3a79f8398fc4dd84a0a046a646a9246f6fd6abc035e27771795554783e18dd5ba3c8efd7e74a9def988dd430397
6
+ metadata.gz: 4c931b3512e64bd8b3c81c4cf643c1a18d88590f5ed373a6827dcd46ea7aced9ae5eb5e88735ff31bdd16971630cfc1bd978bbcd24ee551fdbae7b752c0b1ab1
7
+ data.tar.gz: b957972825b35a55434ff794ca1c77222b46bfc8c51f393c46c15d83fa28f3953f2d02669c284d1af450f99ed771b967ee1b95e4483d0ef411685cc2f5b00388
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- acts_as_trackable (0.4.2)
4
+ acts_as_trackable (0.4.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/changelog.md CHANGED
@@ -1,4 +1,20 @@
1
1
  # acts_as_trackable Changelog
2
+ ## Version: 0.4.4
3
+ ### Patch
4
+ - Critical Fix: Properly cache `nil` when `object_activity` is preloaded but doesn't exist (old records).
5
+ - Prevents N+1 queries when accessing `created_by`/`updated_by` on records without `object_activity`.
6
+ - Previously, the fallback query would execute for each record even when using `includes(object_activity: [:created_by, :updated_by])`.
7
+ - Now correctly returns `nil` without database queries when association is preloaded and empty.
8
+
9
+ ## Version: 0.4.3
10
+ ### Patch
11
+ - Performance Fix: Fixed N+1 query issue when accessing `created_by` and `updated_by` after eager loading.
12
+
13
+ - The `created_by` and `updated_by` methods now properly respect preloaded associations.
14
+ - When using `includes(object_activity: [:created_by, :updated_by])` or `Preloader.new(records: records, associations: { object_activity: %i[created_by updated_by] })`, the methods now use the preloaded data instead of triggering additional database queries.
15
+
16
+ - Added comprehensive test coverage for N+1 query prevention scenarios.
17
+ - Migration Note: This is a non-breaking change. Existing code will continue to work, but performance will improve when using nested eager loading.
2
18
  ## Version: 0.4.2
3
19
  ### Patch
4
20
  - Upgraded dependencies to patch CVE-2025-55193.
@@ -16,21 +16,53 @@ module Trackable
16
16
  if association(:object_activity).loaded?
17
17
  loaded = association(:object_activity).target
18
18
 
19
- if loaded&.object_id == id &&
20
- [self.class.name, self.class.base_class.name].include?(loaded.object_type)
21
- @object_activity = loaded
19
+ # Cache the loaded value (even if nil) to avoid fallback query
20
+ if loaded.nil?
21
+ return @object_activity = nil
22
+ elsif loaded[:object_id] == id &&
23
+ [self.class.name, self.class.base_class.name].include?(loaded.object_type)
24
+ return @object_activity = loaded
22
25
  end
23
26
  end
24
27
 
25
28
  # Fallback to DB query if not preloaded or not matched
26
- @object_activity ||= ObjectActivity.find_by(
29
+ @object_activity = ObjectActivity.find_by(
27
30
  object_id: id,
28
31
  object_type: [self.class.name, self.class.base_class.name]
29
32
  )
30
33
  end
31
34
 
35
+ # Custom created_by method that respects preloading
36
+ define_method :created_by do
37
+ return nil unless object_activity
32
38
 
33
- delegate :created_by, :updated_by, to: :object_activity, allow_nil: true
39
+ # Return cached value if already set
40
+ return @created_by if defined?(@created_by)
41
+
42
+ # Check if created_by is preloaded on the object_activity
43
+ @created_by = if object_activity.association(:created_by).loaded?
44
+ object_activity.association(:created_by).target
45
+ else
46
+ # Fallback to default association behavior
47
+ object_activity.created_by
48
+ end
49
+ end
50
+
51
+ # Custom updated_by method that respects preloading
52
+ define_method :updated_by do
53
+ return nil unless object_activity
54
+
55
+ # Return cached value if already set
56
+ return @updated_by if defined?(@updated_by)
57
+
58
+ # Check if updated_by is preloaded on the object_activity
59
+ @updated_by = if object_activity.association(:updated_by).loaded?
60
+ object_activity.association(:updated_by).target
61
+ else
62
+ # Fallback to default association behavior
63
+ object_activity.updated_by
64
+ end
65
+ end
34
66
 
35
67
  after_commit :log_object_activity, on: %i[create update], if: -> { modifier.present? }
36
68
 
@@ -1,3 +1,3 @@
1
1
  module ActsAsTrackable
2
- VERSION = '0.4.2'.freeze
2
+ VERSION = '0.4.4'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_trackable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmad Keewan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-08-25 00:00:00.000000000 Z
12
+ date: 2025-10-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: generator_spec