counter_culture 3.13.0 → 3.13.2

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: ce955a1cc71481d0223d0477b44823a9ed539e2209a77a0db5a5f90f09d87259
4
- data.tar.gz: 68e564d152930f8fd663acbb99e64c0b5ed7ff451358b4f8439364d807b672c8
3
+ metadata.gz: 8dcb5f1c57a5fda38de103fdcdf767e990f507b994c1d2e59debdbde0b1f3ef3
4
+ data.tar.gz: 8945d83862559fb693b79d1837507c23f978828e3d9c377f2d4cacf67d4843cc
5
5
  SHA512:
6
- metadata.gz: f77b8bece6b1242b3402c08cfece835f59d721ecef1f8330c66dc65a42a2ba6797c605f062e414a9d9a2f55d9113f6aa597176fd0e422221c16ee8f9a2648aaa
7
- data.tar.gz: be715fdc0be1bfa8be1b555fcb28630f770012eee35459865520469a5211ab9f37e0894816cfcbd2d6f015d2704aa0b59eea44ed77a2c2cccdef230c373eac1e
6
+ metadata.gz: 398000f43d6feb9165c54ec2e3614b65bb9f384e8c8f9693d6956ee9e22d2e2eec6bad28b7cdab21b1fd2543fbee05f3f04d7f697a60a740fbdd00e20e960d9b
7
+ data.tar.gz: 7a8e5b137d1266161ff9cb3569005f2acd147829656fc66b1aabcb0bf0d3e0a823bc3398b0b6573c6b01e394f996436a53861949e09560ca5219b414ad67193b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 3.13.2 (June 25, 2026)
2
+
3
+ Bugfixes:
4
+ - Fix multi-level counter caches not being updated in memory when creating or destroying records (#432)
5
+
6
+ ## 3.13.1 (April 20, 2026)
7
+
8
+ Bugfixes:
9
+ - Fix `StaleObjectError` when counter target model has optimistic locking enabled (#429)
10
+
1
11
  ## 3.13.0 (April 9, 2026)
2
12
 
3
13
  New features:
@@ -74,6 +74,12 @@ module CounterCulture
74
74
  # Build Arel expression for non-aggregate case
75
75
  counter_expr = Counter.build_arel_counter_expr(klass, change_counter_column, signed_delta, column_type)
76
76
  arel_updates = { change_counter_column => counter_expr }
77
+
78
+ # Set lock_version = lock_version (no-op) to skip Rails auto-increment
79
+ if klass.locking_enabled?
80
+ lc = klass.locking_column
81
+ arel_updates[lc] = klass.arel_table[lc]
82
+ end
77
83
  end
78
84
 
79
85
  # and this will update the timestamp, if so desired
@@ -404,9 +410,7 @@ module CounterCulture
404
410
 
405
411
  # update associated object counter attribute
406
412
  def assign_to_associated_object(obj, relation, change_counter_column, operator, delta_magnitude)
407
- association_name = relation_reflect(relation).name
408
-
409
- association_object = association_object_for_assign(obj, association_name)
413
+ association_object = association_object_for_assign(obj, relation)
410
414
  return if association_object.blank? || association_object.frozen?
411
415
 
412
416
  association_object.assign_attributes(
@@ -416,21 +420,23 @@ module CounterCulture
416
420
  association_object_clear_change(association_object, change_counter_column)
417
421
  end
418
422
 
419
- def association_object_for_assign(obj, association_name)
420
- if obj.class.reflect_on_all_associations.
421
- find { |assoc| assoc.name.to_sym == association_name.to_sym }.
422
- blank?
423
- # This means that this isn't defined as an association; either it
424
- # doesn't exist at all, or it uses delegate. In either case, we can't
425
- # update the count this way.
426
- return
427
- end
428
- if !obj.association(association_name).loaded?
429
- # If the association isn't loaded, no need to update the count
430
- return
423
+ def association_object_for_assign(obj, relation)
424
+ relation = relation.is_a?(Enumerable) ? relation.dup : [relation]
425
+
426
+ while !obj.nil? && relation.size > 0
427
+ cur_relation = relation.shift
428
+ # This isn't an association (e.g. it uses delegate), so we can't update the count this way
429
+ return nil if obj.class.reflect_on_association(cur_relation).nil?
430
+
431
+ if !obj.association(cur_relation).loaded?
432
+ # If the association isn't loaded, no need to update the count
433
+ return nil
434
+ end
435
+
436
+ obj = obj.public_send(cur_relation)
431
437
  end
432
438
 
433
- obj.public_send(association_name)
439
+ obj
434
440
  end
435
441
 
436
442
  def association_object_clear_change(association_object, change_counter_column)
@@ -1,3 +1,3 @@
1
1
  module CounterCulture
2
- VERSION = '3.13.0'.freeze
2
+ VERSION = '3.13.2'.freeze
3
3
  end
@@ -46,6 +46,12 @@ module CounterCulture
46
46
  end
47
47
 
48
48
  if arel_updates.any?
49
+ # Set lock_version = lock_version (no-op) to skip Rails auto-increment
50
+ if klass.locking_enabled?
51
+ lc = klass.locking_column
52
+ arel_updates[lc] = klass.arel_table[lc]
53
+ end
54
+
49
55
  primary_key = Thread.current[:primary_key_map][klass]
50
56
 
51
57
  conditions =
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: counter_culture
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.0
4
+ version: 3.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus von Koeller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-09 00:00:00.000000000 Z
11
+ date: 2026-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord