counter_culture 3.11.1 → 3.11.3

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: 593e3704f40322fade2c263f93bb6d88749b397d641586b30f4d616ee5c9ed0c
4
- data.tar.gz: b183412de943dbe2390a4eef636ca8aae9fea6aeac6ac298177545d26b08413e
3
+ metadata.gz: 75ac99d8d45f3e16859bb04854958dac048a449aa4afe94f12885cefe3a94787
4
+ data.tar.gz: e90d1b87ea3e2d919434dbeea2263fa5556044dc273cab21a6a67b423519c012
5
5
  SHA512:
6
- metadata.gz: c0a74d87a9d56ec4b19d7fe9a7aaf9bd2698d527387251a52b866e534117386005e830eef556b96bbc67122a125ebf942a4531be5b6f2d35a075b55b3133b052
7
- data.tar.gz: 4cd891261ed5402cffa7eea851e2400f3b6d7ec8c4d617b36a3b0dd680e00f17b9b1a909a55bb94db1dbe636ca4b5d2d929d02df851e00869bb316a703fa8928
6
+ metadata.gz: dc1196535a528c5f87e39aca06d5e1a3e014f469c8aa3e8f01c56f75a59489c4db25dc9b67168b162ddf9ac24e45c55fe887c10176e76786dea5ffe72603f10b
7
+ data.tar.gz: a949a3856773028e954e00c8ce5ba89ac0e999230c47af3d1b0e312fdef827cbbf0dc71ed91406c6b2b77ba4d194b108f21df8b904f0e09592d2b5ef2a0e25d9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 3.11.3 (October 22, 2025)
2
+
3
+ Bugfixes:
4
+ - Fix in-memory counter updates for conditional counters when condition changes (#420)
5
+
6
+ ## 3.11.2 (July 10, 2025)
7
+
8
+ Bugfixes:
9
+ - Fix regression for foreign_key_values by adding support for composite primary keys (#417)
10
+
1
11
  ## 3.11.1 (June 27, 2025)
2
12
 
3
13
  Bugfixes:
data/README.md CHANGED
@@ -232,7 +232,7 @@ The ```:delta_column``` option supports all numeric column types, not just ```:i
232
232
  class Product < ActiveRecord::Base
233
233
  belongs_to :category
234
234
  counter_culture :category, foreign_key_values:
235
- proc {|category_id| [category_id, Category.find_by_id(category_id).try(:parent_category).try(:id)] }
235
+ proc {|category_id| [category_id, Category.find_by(id: category_id)&.parent_category&.id] }
236
236
  end
237
237
 
238
238
  class Category < ActiveRecord::Base
@@ -108,6 +108,15 @@ module CounterCulture
108
108
 
109
109
  primary_key = relation_primary_key(relation, source: obj, was: options[:was])
110
110
 
111
+ if foreign_key_values && id_to_change.is_a?(Enumerable) && id_to_change.count > 1 &&
112
+ Array.wrap(primary_key).count == 1
113
+ # To keep this feature backwards compatible, we need to accommodate a case where
114
+ # `foreign_key_values` returns an array, but we're _not_ using composite primary
115
+ # keys. In that case, we need to wrap the `id_to_change` in one more array to keep
116
+ # it compatible with the `.zip` call in `primary_key_conditions`.
117
+ id_to_change = [id_to_change]
118
+ end
119
+
111
120
  if Thread.current[:aggregate_counter_updates]
112
121
  Thread.current[:primary_key_map][klass] ||= primary_key
113
122
  end
@@ -141,7 +150,27 @@ module CounterCulture
141
150
  execute_now_or_after_commit(obj) do
142
151
  conditions = primary_key_conditions(primary_key, id_to_change)
143
152
  klass.where(conditions).update_all updates.join(', ')
144
- unless options[:was]
153
+ # Determine if we should update the in-memory counter on the associated object.
154
+ # When updating the old counter (was: true), we need to carefully consider two scenarios:
155
+ # 1) The belongs_to relation changed (e.g., moving a child from parent A to parent B):
156
+ # In this case, obj.association now points to parent B, but we're decrementing parent A's
157
+ # counter. We should NOT update the in-memory counter because it would incorrectly
158
+ # modify parent B's cached value.
159
+ # 2) A conditional counter's condition changed (e.g., condition: true → false):
160
+ # In this case, obj.association still points to the same parent, but the counter column
161
+ # name changed (e.g., from 'conditional_count' to nil). We SHOULD update the in-memory
162
+ # counter so the parent object reflects the decremented value without requiring a reload.
163
+ # We distinguish these cases by comparing foreign keys: if the current and previous foreign
164
+ # keys are identical, we're in scenario 2 and should update the in-memory counter.
165
+ should_update_counter = if options[:was]
166
+ current_fk = foreign_key_value(obj, relation, false)
167
+ previous_fk = foreign_key_value(obj, relation, true)
168
+ current_fk == previous_fk && current_fk.present?
169
+ else
170
+ true
171
+ end
172
+
173
+ if should_update_counter
145
174
  assign_to_associated_object(obj, relation, change_counter_column, operator, delta_magnitude)
146
175
  end
147
176
  end
@@ -1,3 +1,3 @@
1
1
  module CounterCulture
2
- VERSION = '3.11.1'.freeze
2
+ VERSION = '3.11.3'.freeze
3
3
  end
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.11.1
4
+ version: 3.11.3
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: 2025-06-27 00:00:00.000000000 Z
11
+ date: 2025-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord