Skip to content

Commit e94e97c

Browse files
author
David Heinemeier Hansson
committed
Extend ActiveRecord::Base#cache_key to take an optional list of timestamp attributes of which the highest will be used.
1 parent 6d30219 commit e94e97c

File tree

4 files changed

+27
-2
lines changed

4 files changed

+27
-2
lines changed

activerecord/CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
* Extend ActiveRecord::Base#cache_key to take an optional list of timestamp attributes of which the highest will be used.
2+
3+
Example:
4+
5+
# last_reviewed_at will be used, if that's more recent than updated_at, or vice versa
6+
Person.find(5).cache_key(:updated_at, :last_reviewed_at)
7+
8+
*DHH*
9+
10+
111
* Added ActiveRecord::Base#enum for declaring enum attributes where the values map to integers in the database, but can be queried by name.
212

313
Example:

activerecord/lib/active_record/integration.rb

+9-1
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,18 @@ def to_param
4545
# Product.new.cache_key # => "products/new"
4646
# Product.find(5).cache_key # => "products/5" (updated_at not available)
4747
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
48-
def cache_key
48+
#
49+
# You can also pass a list of named timestamps, and the newest in the list will be
50+
# used to generate the key:
51+
#
52+
# Person.find(5).cache_key(:updated_at, :last_reviewed_at)
53+
def cache_key(*timestamp_names)
4954
case
5055
when new_record?
5156
"#{self.class.model_name.cache_key}/new"
57+
when timestamp_names.any?
58+
timestamps = timestamp_names.collect { |method| send(method) }.compact
59+
"#{self.class.model_name.cache_key}/#{id}-#{timestamps.max.utc.to_s(:number)}"
5260
when timestamp = max_updated_column_timestamp
5361
timestamp = timestamp.utc.to_s(cache_timestamp_format)
5462
"#{self.class.model_name.cache_key}/#{id}-#{timestamp}"

activerecord/test/cases/integration_test.rb

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
require 'models/developer'
44
require 'models/car'
55
require 'models/bulb'
6+
require 'models/owner'
67

78
class IntegrationTest < ActiveRecord::TestCase
8-
fixtures :companies, :developers
9+
fixtures :companies, :developers, :owners
910

1011
def test_to_param_should_return_string
1112
assert_kind_of String, Client.first.to_param
@@ -81,4 +82,9 @@ def test_cache_key_format_is_precise_enough
8182
dev.touch
8283
assert_not_equal key, dev.cache_key
8384
end
85+
86+
def test_named_timestamps_for_cache_key
87+
owner = owners(:blackbeard)
88+
assert_equal "owners/#{owner.id}-#{owner.happy_at.utc.to_s(:number)}", owner.cache_key(:updated_at, :happy_at)
89+
end
8490
end

activerecord/test/fixtures/owners.yml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ blackbeard:
22
owner_id: 1
33
name: blackbeard
44
essay_id: A Modest Proposal
5+
happy_at: '2150-10-10 16:00:00'
56

67
ashley:
78
owner_id: 2

0 commit comments

Comments
 (0)