diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-04-04 13:54:37 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-04 13:54:37 +0900 |
commit | 39d42dbde2571a9a713007c1a8e9f202e004cdeb (patch) | |
tree | c3e270f76a71b6a58e751fdf8a14981bbe6d4dbc | |
parent | d49761cd66f55e18e0a7ee5138de0649c18654f0 (diff) | |
parent | 10919bfef2303c3409b15ed1d9405f3b4c518507 (diff) | |
download | rails-39d42dbde2571a9a713007c1a8e9f202e004cdeb.tar.gz rails-39d42dbde2571a9a713007c1a8e9f202e004cdeb.tar.bz2 rails-39d42dbde2571a9a713007c1a8e9f202e004cdeb.zip |
Merge pull request #35848 from kamipo/refactor_collection_cache_key
Refactor `Relation#cache_key` is moved from `CollectionCacheKey#collection_cache_key`
-rw-r--r-- | activerecord/lib/active_record.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/active_record/base.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/active_record/collection_cache_key.rb | 52 | ||||
-rw-r--r-- | activerecord/lib/active_record/integration.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 45 |
5 files changed, 49 insertions, 54 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 7d66158f47..fd8d2edf28 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -55,7 +55,6 @@ module ActiveRecord autoload :Persistence autoload :QueryCache autoload :Querying - autoload :CollectionCacheKey autoload :ReadonlyAttributes autoload :RecordInvalid, "active_record/validations" autoload :Reflection diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index db097cb930..2af6d09b53 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -288,7 +288,6 @@ module ActiveRecord #:nodoc: extend Explain extend Enum extend Delegation::DelegateCache - extend CollectionCacheKey extend Aggregations::ClassMethods include Core diff --git a/activerecord/lib/active_record/collection_cache_key.rb b/activerecord/lib/active_record/collection_cache_key.rb deleted file mode 100644 index bfcb3e54be..0000000000 --- a/activerecord/lib/active_record/collection_cache_key.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module ActiveRecord - module CollectionCacheKey - def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc: - query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql) - key = "#{collection.model_name.cache_key}/query-#{query_signature}" - - if collection.loaded? || collection.distinct_value - size = collection.records.size - if size > 0 - timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column) - end - else - if collection.eager_loading? - collection = collection.send(:apply_join_dependency) - end - column_type = type_for_attribute(timestamp_column) - column = connection.visitor.compile(collection.arel_attribute(timestamp_column)) - select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp" - - if collection.has_limit_or_offset? - query = collection.select("#{column} AS collection_cache_key_timestamp") - subquery_alias = "subquery_for_cache_key" - subquery_column = "#{subquery_alias}.collection_cache_key_timestamp" - arel = query.send(:build_subquery, subquery_alias, select_values % subquery_column) - else - query = collection.unscope(:order) - query.select_values = [select_values % column] - arel = query.arel - end - - result = connection.select_one(arel, nil) - - if result.blank? - size = 0 - timestamp = nil - else - size = result["size"] - timestamp = column_type.deserialize(result["timestamp"]) - end - - end - - if timestamp - "#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}" - else - "#{key}-#{size}" - end - end - end -end diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb index 67a63cd2d1..b769541e95 100644 --- a/activerecord/lib/active_record/integration.rb +++ b/activerecord/lib/active_record/integration.rb @@ -152,6 +152,10 @@ module ActiveRecord end end end + + def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc: + collection.compute_cache_key(timestamp_column) + end end private diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index dd821431e1..c1ef98c063 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -317,6 +317,51 @@ module ActiveRecord @cache_keys[timestamp_column] ||= @klass.collection_cache_key(self, timestamp_column) end + def compute_cache_key(timestamp_column = :updated_at) # :nodoc: + query_signature = ActiveSupport::Digest.hexdigest(to_sql) + key = "#{klass.model_name.cache_key}/query-#{query_signature}" + + if loaded? || distinct_value + size = records.size + if size > 0 + timestamp = max_by(×tamp_column)._read_attribute(timestamp_column) + end + else + collection = eager_loading? ? apply_join_dependency : self + + column = connection.visitor.compile(arel_attribute(timestamp_column)) + select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp" + + if collection.has_limit_or_offset? + query = collection.select("#{column} AS collection_cache_key_timestamp") + subquery_alias = "subquery_for_cache_key" + subquery_column = "#{subquery_alias}.collection_cache_key_timestamp" + arel = query.build_subquery(subquery_alias, select_values % subquery_column) + else + query = collection.unscope(:order) + query.select_values = [select_values % column] + arel = query.arel + end + + result = connection.select_one(arel, nil) + + if result + column_type = klass.type_for_attribute(timestamp_column) + timestamp = column_type.deserialize(result["timestamp"]) + size = result["size"] + else + timestamp = nil + size = 0 + end + end + + if timestamp + "#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}" + else + "#{key}-#{size}" + end + end + # Scope all queries to the current scope. # # Comment.where(post_id: 1).scoping do |