@@ -317,6 +317,51 @@ def cache_key(timestamp_column = :updated_at)
317
317
@cache_keys [ timestamp_column ] ||= @klass . collection_cache_key ( self , timestamp_column )
318
318
end
319
319
320
+ def compute_cache_key ( timestamp_column = :updated_at ) # :nodoc:
321
+ query_signature = ActiveSupport ::Digest . hexdigest ( to_sql )
322
+ key = "#{ klass . model_name . cache_key } /query-#{ query_signature } "
323
+
324
+ if loaded? || distinct_value
325
+ size = records . size
326
+ if size > 0
327
+ timestamp = max_by ( ×tamp_column ) . _read_attribute ( timestamp_column )
328
+ end
329
+ else
330
+ collection = eager_loading? ? apply_join_dependency : self
331
+
332
+ column = connection . visitor . compile ( arel_attribute ( timestamp_column ) )
333
+ select_values = "COUNT(*) AS #{ connection . quote_column_name ( "size" ) } , MAX(%s) AS timestamp"
334
+
335
+ if collection . has_limit_or_offset?
336
+ query = collection . select ( "#{ column } AS collection_cache_key_timestamp" )
337
+ subquery_alias = "subquery_for_cache_key"
338
+ subquery_column = "#{ subquery_alias } .collection_cache_key_timestamp"
339
+ arel = query . build_subquery ( subquery_alias , select_values % subquery_column )
340
+ else
341
+ query = collection . unscope ( :order )
342
+ query . select_values = [ select_values % column ]
343
+ arel = query . arel
344
+ end
345
+
346
+ result = connection . select_one ( arel , nil )
347
+
348
+ if result
349
+ column_type = klass . type_for_attribute ( timestamp_column )
350
+ timestamp = column_type . deserialize ( result [ "timestamp" ] )
351
+ size = result [ "size" ]
352
+ else
353
+ timestamp = nil
354
+ size = 0
355
+ end
356
+ end
357
+
358
+ if timestamp
359
+ "#{ key } -#{ size } -#{ timestamp . utc . to_s ( cache_timestamp_format ) } "
360
+ else
361
+ "#{ key } -#{ size } "
362
+ end
363
+ end
364
+
320
365
# Scope all queries to the current scope.
321
366
#
322
367
# Comment.where(post_id: 1).scoping do
0 commit comments