counter_culture 3.11.2 → 3.11.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 +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/counter_culture/counter.rb +33 -4
- data/lib/counter_culture/reconciler.rb +6 -6
- data/lib/counter_culture/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4978dfaab9ec73c8b3215c2d2f811093cc00cdf7daccfe877749f301a09ae11a
|
|
4
|
+
data.tar.gz: e2e1322882fdeab8c7239c7cf16e4019b5450d3f435c478ad1d9e2d33cf5a251
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a60b46c8b713dbbb7f2969c9b6885e9975a1c5723eb3566a04b011380eafb077c3051386586cff7c77b5ba171888ef577aa5d1dd6be4a4d97ea8e1db1fdca91d
|
|
7
|
+
data.tar.gz: 51feccb08cf927e8fc6f1d41f39f91269411db70d96d3b44d57ddf35c67130790c1340cb27aff0e0f4701934b40bc17485345667d1bffcbfb145eb4a5d98bea6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 3.11.4 (November 5, 2025)
|
|
2
|
+
|
|
3
|
+
Bugfixes:
|
|
4
|
+
- Fix counter cache not using the correct type with multiple STI models in the association chain (#421)
|
|
5
|
+
|
|
6
|
+
## 3.11.3 (October 22, 2025)
|
|
7
|
+
|
|
8
|
+
Bugfixes:
|
|
9
|
+
- Fix in-memory counter updates for conditional counters when condition changes (#420)
|
|
10
|
+
|
|
1
11
|
## 3.11.2 (July 10, 2025)
|
|
2
12
|
|
|
3
13
|
Bugfixes:
|
|
@@ -150,7 +150,27 @@ module CounterCulture
|
|
|
150
150
|
execute_now_or_after_commit(obj) do
|
|
151
151
|
conditions = primary_key_conditions(primary_key, id_to_change)
|
|
152
152
|
klass.where(conditions).update_all updates.join(', ')
|
|
153
|
-
|
|
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
|
|
154
174
|
assign_to_associated_object(obj, relation, change_counter_column, operator, delta_magnitude)
|
|
155
175
|
end
|
|
156
176
|
end
|
|
@@ -220,11 +240,11 @@ module CounterCulture
|
|
|
220
240
|
Array.wrap(primary_key).map { |pk| value.try(pk&.to_sym) }.compact.presence
|
|
221
241
|
end
|
|
222
242
|
|
|
223
|
-
# gets the reflect object on the given relation
|
|
243
|
+
# gets the reflect object on the given relation and the model that defines this reflect
|
|
224
244
|
#
|
|
225
245
|
# relation: a symbol or array of symbols; specifies the relation
|
|
226
246
|
# that has the counter cache column
|
|
227
|
-
def
|
|
247
|
+
def relation_reflect_and_model(relation)
|
|
228
248
|
relation = relation.is_a?(Enumerable) ? relation.dup : [relation]
|
|
229
249
|
|
|
230
250
|
# go from one relation to the next until we hit the last reflect object
|
|
@@ -242,7 +262,16 @@ module CounterCulture
|
|
|
242
262
|
end
|
|
243
263
|
end
|
|
244
264
|
|
|
245
|
-
return reflect
|
|
265
|
+
return [reflect, klass]
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# gets the reflect object on the given relation
|
|
270
|
+
#
|
|
271
|
+
# relation: a symbol or array of symbols; specifies the relation
|
|
272
|
+
# that has the counter cache column
|
|
273
|
+
def relation_reflect(relation)
|
|
274
|
+
relation_reflect_and_model(relation).first
|
|
246
275
|
end
|
|
247
276
|
|
|
248
277
|
# gets the class of the given relation
|
|
@@ -59,7 +59,7 @@ module CounterCulture
|
|
|
59
59
|
class Reconciliation
|
|
60
60
|
attr_reader :counter, :options, :relation_class
|
|
61
61
|
|
|
62
|
-
delegate :model, :relation, :full_primary_key, :relation_reflect, :polymorphic?, :to => :counter
|
|
62
|
+
delegate :model, :relation, :full_primary_key, :relation_reflect_and_model, :relation_reflect, :polymorphic?, :to => :counter
|
|
63
63
|
delegate *CounterCulture::Counter::CONFIG_OPTIONS, :to => :counter
|
|
64
64
|
|
|
65
65
|
def initialize(counter, changes_holder, options, relation_class)
|
|
@@ -257,11 +257,11 @@ module CounterCulture
|
|
|
257
257
|
# store joins in an array so that we can later apply column-specific
|
|
258
258
|
# conditions
|
|
259
259
|
join_clauses = reverse_relation.each_with_index.map do |cur_relation, index|
|
|
260
|
-
reflect =
|
|
260
|
+
reflect, model = relation_reflect_and_model(cur_relation)
|
|
261
261
|
|
|
262
|
-
target_table = quote_table_name(
|
|
262
|
+
target_table = quote_table_name(model.table_name)
|
|
263
263
|
target_table_alias = parameterize(target_table)
|
|
264
|
-
if relation_class.table_name ==
|
|
264
|
+
if relation_class.table_name == model.table_name
|
|
265
265
|
# join with alias to avoid ambiguous table name in
|
|
266
266
|
# self-referential models
|
|
267
267
|
target_table_alias += "_#{target_table_alias}"
|
|
@@ -299,8 +299,8 @@ module CounterCulture
|
|
|
299
299
|
|
|
300
300
|
# adds 'type' condition to JOIN clause if the current model is a
|
|
301
301
|
# child in a Single Table Inheritance
|
|
302
|
-
if
|
|
303
|
-
|
|
302
|
+
if model.column_names.include?('type') &&
|
|
303
|
+
!model.descends_from_active_record?
|
|
304
304
|
joins_sql += " AND #{target_table_alias}.type IN ('#{model.name}')"
|
|
305
305
|
end
|
|
306
306
|
if polymorphic?
|
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.
|
|
4
|
+
version: 3.11.4
|
|
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-
|
|
11
|
+
date: 2025-11-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|