Skip to content

Commit 39d42db

Browse files
authored
Merge pull request rails#35848 from kamipo/refactor_collection_cache_key
Refactor `Relation#cache_key` is moved from `CollectionCacheKey#collection_cache_key`
2 parents d49761c + 10919bf commit 39d42db

File tree

5 files changed

+49
-54
lines changed

5 files changed

+49
-54
lines changed

activerecord/lib/active_record.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ module ActiveRecord
5555
autoload :Persistence
5656
autoload :QueryCache
5757
autoload :Querying
58-
autoload :CollectionCacheKey
5958
autoload :ReadonlyAttributes
6059
autoload :RecordInvalid, "active_record/validations"
6160
autoload :Reflection

activerecord/lib/active_record/base.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ class Base
288288
extend Explain
289289
extend Enum
290290
extend Delegation::DelegateCache
291-
extend CollectionCacheKey
292291
extend Aggregations::ClassMethods
293292

294293
include Core

activerecord/lib/active_record/collection_cache_key.rb

Lines changed: 0 additions & 52 deletions
This file was deleted.

activerecord/lib/active_record/integration.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ def to_param(method_name = nil)
152152
end
153153
end
154154
end
155+
156+
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
157+
collection.compute_cache_key(timestamp_column)
158+
end
155159
end
156160

157161
private

activerecord/lib/active_record/relation.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,51 @@ def cache_key(timestamp_column = :updated_at)
317317
@cache_keys[timestamp_column] ||= @klass.collection_cache_key(self, timestamp_column)
318318
end
319319

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(&timestamp_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+
320365
# Scope all queries to the current scope.
321366
#
322367
# Comment.where(post_id: 1).scoping do

0 commit comments

Comments
 (0)