From 9cce1ea2fd02e8050350c4657e7cc7f1902b8694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 10 Dec 2012 16:22:30 -0300 Subject: [PATCH] Allow users to choose the timestamp format in the cache key This can be done using the class attribute cache_timestamp_format Conflicts: railties/guides/source/configuring.textile --- activerecord/CHANGELOG.md | 7 +++++++ activerecord/lib/active_record/integration.rb | 13 ++++++++++++- activerecord/test/cases/base_test.rb | 5 +++++ activerecord/test/models/developer.rb | 5 +++++ guides/source/configuring.md | 2 ++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 02aced31c9..d4e3a33002 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,12 @@ ## Rails 4.0.0 (unreleased) ## +* Add `ActiveRecord::Base.cache_timestamp_format` class attribute to control + the format of the timestamp value in the cache key. + This allows users to improve the precision of the cache key. + Fixes #8195. + + *Rafael Mendonça França* + * Fix decorating columns for serialized attributes. Fixes #8441 *itzki* diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb index 7bdc1bd4c6..7f877a6471 100644 --- a/activerecord/lib/active_record/integration.rb +++ b/activerecord/lib/active_record/integration.rb @@ -1,5 +1,16 @@ module ActiveRecord module Integration + extend ActiveSupport::Concern + + included do + ## + # :singleton-method: + # Indicates the format used to generate the timestamp format in the cache key. + # This is +:number+, by default. + class_attribute :cache_timestamp_format, :instance_writer => false + self.cache_timestamp_format = :nsec + end + # Returns a String, which Action Pack uses for constructing an URL to this # object. The default implementation returns this record's id as a String, # or nil if this record's unsaved. @@ -37,7 +48,7 @@ module ActiveRecord when new_record? "#{self.class.model_name.cache_key}/new" when timestamp = self[:updated_at] - timestamp = timestamp.utc.to_s(:nsec) + timestamp = timestamp.utc.to_s(cache_timestamp_format) "#{self.class.model_name.cache_key}/#{id}-#{timestamp}" else "#{self.class.model_name.cache_key}/#{id}" diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index e4445698dc..c5c500279e 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1444,6 +1444,11 @@ class BasicsTest < ActiveRecord::TestCase assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_s(:nsec)}", dev.cache_key end + def test_cache_key_format_for_existing_record_with_updated_at_and_cache_timestamp_format_set + dev = CachedDeveloper.first + assert_equal "cached_developers/#{dev.id}-#{dev.updated_at.utc.to_s(:number)}", dev.cache_key + end + def test_cache_key_changes_when_child_touched car = Car.create Bulb.create(car: car) diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 1c048bb6b4..683cb54a10 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -234,3 +234,8 @@ class ThreadsafeDeveloper < ActiveRecord::Base limit(1) end end + +class CachedDeveloper < ActiveRecord::Base + self.table_name = "developers" + self.cache_timestamp_format = :number +end diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 446f767f0c..a8e33a2956 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -276,6 +276,8 @@ config.middleware.delete ActionDispatch::BestStandardsSupport * `config.active_record.auto_explain_threshold_in_seconds` configures the threshold for automatic EXPLAINs (`nil` disables this feature). Queries exceeding the threshold get their query plan logged. Default is 0.5 in development mode. +* +config.active_record.cache_timestamp_format+ controls the format of the timestamp value in the cache key. Default is +:number+. + The MySQL adapter adds one additional configuration option: * `ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns in a MySQL database to be booleans and is true by default.