cache-machine 0.1.10 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -1
- data/.travis.yml +6 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +0 -2
- data/README.md +258 -0
- data/VERSION +1 -1
- data/cache-machine.gemspec +7 -22
- data/db/.gitignore +1 -0
- data/lib/cache-machine.rb +6 -2
- data/lib/cache_machine/adapter.rb +127 -0
- data/lib/cache_machine/adapters/rails.rb +58 -0
- data/lib/cache_machine/cache.rb +34 -85
- data/lib/cache_machine/cache/associations.rb +29 -0
- data/lib/cache_machine/cache/class_timestamp.rb +31 -0
- data/lib/cache_machine/cache/collection.rb +131 -0
- data/lib/cache_machine/cache/map.rb +97 -241
- data/lib/cache_machine/cache/mapper.rb +135 -0
- data/lib/cache_machine/cache/resource.rb +108 -0
- data/lib/cache_machine/cache/scope.rb +24 -0
- data/lib/cache_machine/cache/timestamp_builder.rb +58 -0
- data/lib/cache_machine/helpers/cache_helper.rb +3 -3
- data/lib/cache_machine/logger.rb +9 -8
- data/lib/cache_machine/railtie.rb +11 -0
- data/lib/cache_machine/tasks.rb +10 -0
- data/spec/fixtures.rb +11 -6
- data/spec/lib/cache_machine/adapters/rails_spec.rb +149 -0
- data/spec/lib/cache_machine/cache/associations_spec.rb +32 -0
- data/spec/lib/cache_machine/cache/class_timestam_spec.rb +29 -0
- data/spec/lib/cache_machine/cache/collection_spec.rb +106 -0
- data/spec/lib/cache_machine/cache/map_spec.rb +34 -0
- data/spec/lib/cache_machine/cache/mapper_spec.rb +61 -0
- data/spec/lib/cache_machine/cache/resource_spec.rb +86 -0
- data/spec/lib/cache_machine/cache/scope_spec.rb +50 -0
- data/spec/lib/cache_machine/cache/timestamp_builder_spec.rb +52 -0
- data/spec/spec_helper.rb +9 -3
- metadata +35 -61
- data/README.rdoc +0 -186
- data/spec/lib/cache_machine_spec.rb +0 -161
data/.gitignore
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.8.7
|
4
|
+
- 1.9.2
|
5
|
+
- 1.9.3
|
6
|
+
script: bundle exec rspec spec/lib/cache_machine/adapters/rails_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/associations_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/class_timestam_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/collection_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/map_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/mapper_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/resource_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/scope_spec.rb && bundle exec rspec spec/lib/cache_machine/cache/timestamp_builder_spec.rb
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
# ![cache-machine](http://img195.imageshack.us/img195/5371/cachemachinefinal2.png)
|
2
|
+
|
3
|
+
An ActiveRecord mixin that helps managing cached content in a Ruby on Rails application with complex data update dependencies.
|
4
|
+
|
5
|
+
Cache Machine provides:
|
6
|
+
|
7
|
+
- high-level methods for accessing cached content using page names, numbers, time stamps etc,
|
8
|
+
- a DSL to describe update dependencies between the data models underlying the cached content,
|
9
|
+
- automatic cache invalidation based on those explicitly modeled data update dependencies.
|
10
|
+
|
11
|
+
You will find Cache Machine useful if you:
|
12
|
+
|
13
|
+
- use Memcache to cache fragments of a web site that contain data from a variety of underlying data models
|
14
|
+
- anytime one of the underlying data models changes, all the cached page fragments in which this data model occurs - and only those - need to be invalidated/updated
|
15
|
+
- you have many data models, cached fragments, and many data models used inside each cached fragment
|
16
|
+
- you want to update cache from background job (i.e. cache-sweeper does not know about your changes)
|
17
|
+
|
18
|
+
Cache Machine is library agnostic. You can use your own cache adapters (see below).
|
19
|
+
|
20
|
+
# Usage
|
21
|
+
|
22
|
+
Setup your cache dependencies in config/initializers/cache-machine.rb using <b>cache map</b>. Very similar to Rails routes:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
CacheMachine::Cache::Map.new.draw do
|
26
|
+
resource City do
|
27
|
+
collection :streets do
|
28
|
+
member :houses
|
29
|
+
end
|
30
|
+
|
31
|
+
collection :houses do
|
32
|
+
member :bricks
|
33
|
+
member :windows
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
resource Street do
|
38
|
+
collection :houses
|
39
|
+
collection :walls
|
40
|
+
end
|
41
|
+
|
42
|
+
resource House do
|
43
|
+
collection :walls, :scope => :vertical, :timestamp => false do
|
44
|
+
members :front_walls, :side_walls
|
45
|
+
member :bricks
|
46
|
+
member :windows
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
In this case your models should look like this:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class City < ActiveRecord::Base
|
56
|
+
has_many :streets
|
57
|
+
has_many :houses, :through => :streets
|
58
|
+
end
|
59
|
+
|
60
|
+
class Street < ActiveRecord::Base
|
61
|
+
belongs_to :city
|
62
|
+
has_many :houses
|
63
|
+
has_many :walls, :through => :houses
|
64
|
+
end
|
65
|
+
|
66
|
+
class House < ActiveRecord::Base
|
67
|
+
belongs_to :street
|
68
|
+
has_many :walls
|
69
|
+
end
|
70
|
+
|
71
|
+
class Wall < ActiveRecord::Base
|
72
|
+
belongs_to :house
|
73
|
+
# has_many :bricks
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
This example shows you how changes in your database affect on cache:
|
78
|
+
|
79
|
+
- When you create/update/destroy any <b>wall</b>:
|
80
|
+
- cache of <b>walls collection</b> expired for <b>house</b> associated with that updated/created/destroyed wall
|
81
|
+
- cache of <b>walls collection</b> expired for <b>street</b> (where wall's house is located) associated with that updated/created/destroyed
|
82
|
+
- cache of <b>front_walls</b> and <b>side_walls</b> expired for <b>house</b> associated with that updated/created/destroyed wall
|
83
|
+
- cache of <b>bricks</b> expired for <b>house</b> associated with that updated/created/destroyed wall
|
84
|
+
- cache of <b>windows</b> expired for <b>house</b> associated with that updated/created/destroyed wall
|
85
|
+
- When you create/update/destroy any <b>house</b>:
|
86
|
+
- cache of <b>houses</b> updated for associated <b>street</b>
|
87
|
+
- cache of <b>houses</b> updated for associated <b>city</b>
|
88
|
+
- When you create/update/destroy any <b>street</b>:
|
89
|
+
- cache of <b>streets</b> updated for associated <b>city</b>
|
90
|
+
- cache of <b>houses</b> updated for associated <b>city</b>
|
91
|
+
- ... :)
|
92
|
+
|
93
|
+
<b>Member may have any name, whatever you want. But invalidation process starts only when collection is changed.</b>
|
94
|
+
|
95
|
+
## Custom cache invalidation
|
96
|
+
|
97
|
+
### Using timestamps
|
98
|
+
Timestamps allow you to build very complex and custom cache dependencies.
|
99
|
+
|
100
|
+
In your model:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
class House < ActiveRecord::Base
|
104
|
+
define_timestamp(:walls_timestamp) { [ bricks.count, windows.last.updated_at ] }
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
Anywhere else:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
@house.fetch_cache_of :walls, :timestamp => :walls_timestamp do
|
112
|
+
walls.where(:built_at => Date.today)
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
This way you add additional condition to cache-key used for fetching data from cache:
|
117
|
+
Any time when bricks count is changed or any window is updated your cache key will be changed and block will return fresh data.
|
118
|
+
Timestamp should return array or string.
|
119
|
+
|
120
|
+
### Using Cache Machine timestamps
|
121
|
+
Suppose you need to reset cache of _tweets_ every 10 minutes.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class LadyGaga < ActiveRecord::Base
|
125
|
+
define_timestamp :tweets_timestamp, :expires_in => 10.minutes do
|
126
|
+
...
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
#...
|
131
|
+
|
132
|
+
# Somewhere
|
133
|
+
@lady_gaga.fetch_cache_of :tweets, :timestamp => :tweets_timestamp do
|
134
|
+
TwitterApi.fetch_tweets_for @lady_gaga
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
```fetch_cache_of``` block uses same options as Rails.cache.fetch. You can easily add _expires_in_ option in it directly.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
@house.fetch_cache :bricks, :expires_in => 1.minute do
|
142
|
+
...
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
Cache Machine stores timestamps for each of your model declared as resource in cache map.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
House.timestamp
|
150
|
+
```
|
151
|
+
Each time your houses collection is changed timestamp will change its value.
|
152
|
+
You can disable this callback in your cache map:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
CacheMachine::Cache::Map.new.draw do
|
156
|
+
resource House, :timestamp => false
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
### Manual cache invalidation
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# For classes.
|
164
|
+
House.reset_timestamp
|
165
|
+
|
166
|
+
# For collections.
|
167
|
+
@house.delete_cache :bricks
|
168
|
+
|
169
|
+
# For timestamps.
|
170
|
+
@house.reset_timestamp :bricks
|
171
|
+
|
172
|
+
# You can reset all associated caches using map.
|
173
|
+
@house.delete_all_caches
|
174
|
+
```
|
175
|
+
|
176
|
+
## Associations cache
|
177
|
+
You can fetch ids of an association from cache.
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
@house.association_ids(:bricks) # will return array of ids
|
181
|
+
```
|
182
|
+
You can fetch associated objects from cache.
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
@house.associated_from_cache(:bricks) # will return scope of relation with condition to ids from cache map.
|
186
|
+
```
|
187
|
+
|
188
|
+
## ActionView helper
|
189
|
+
From examples above:
|
190
|
+
|
191
|
+
```erb
|
192
|
+
<%= cache_for @lady_gaga, :upcoming_events, :timestamp => :each_hour do %>
|
193
|
+
<p>Don't hide yourself in regret
|
194
|
+
Just love yourself and you're set</p>
|
195
|
+
<% end %>
|
196
|
+
```
|
197
|
+
|
198
|
+
## Adapters
|
199
|
+
Cache Machine supports different types for storing cache:
|
200
|
+
|
201
|
+
- <b>cache map adapter</b> contains ids of relationships for each object from cache map
|
202
|
+
- <b>timestamps adapter</b> contains timestamps
|
203
|
+
- <b>content (storage) adapter</b> contains cached content itself (usually strings, html, etc)
|
204
|
+
|
205
|
+
You can setup custom adapters in your environment:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
url = "redis://user:pass@host.com:9383/"
|
209
|
+
uri = URI.parse(url)
|
210
|
+
CacheMachine::Cache.timestamps_adapter = CacheMachine::Adapters::Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
|
211
|
+
CacheMachine::Cache.storage_adapter = CacheMachine::Adapters::Rails.new
|
212
|
+
CacheMachine::Cache.map_adapter = CacheMachine::Adapters::Rails.new
|
213
|
+
```
|
214
|
+
Default adapter uses standard ```Rails.cache``` API.
|
215
|
+
|
216
|
+
Redis adapter is available in cache-machine-redis gem, please check out [here](http://github.com/zininserge/cache-machine-redis).
|
217
|
+
|
218
|
+
## Rake tasks
|
219
|
+
Cache machine will produce SQL queries on each update in collection until all map of associations will stored in cache.
|
220
|
+
You can "prefill" cache map running:
|
221
|
+
|
222
|
+
```rake cache_machine:fill_associations_map```
|
223
|
+
|
224
|
+
Rake accepts model names as params. Each of these models must be defined as resource in cache map:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
CacheMachine::Cache::Map.new.draw do
|
228
|
+
resource House
|
229
|
+
resource Wall
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
```rake cache_machine:fill_associations_map[House, Wall]```
|
234
|
+
|
235
|
+
If all objects from database is too much for you, add additional scope to resource or collection:
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
CacheMachine::Cache::Map.new.draw do
|
239
|
+
resource House, :scope => :offices do
|
240
|
+
collection :bricks, :scope => :squared
|
241
|
+
end
|
242
|
+
resource Wall
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
## Contributing to cache-machine
|
247
|
+
|
248
|
+
1. Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
249
|
+
2. Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
250
|
+
3. Fork the project
|
251
|
+
4. Start a feature/bugfix branch
|
252
|
+
5. Commit and push until you are happy with your contribution
|
253
|
+
6. Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
254
|
+
7. Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
255
|
+
|
256
|
+
## Copyright
|
257
|
+
|
258
|
+
Copyright (c) 2011 PartyEarth LLC. See LICENSE.txt for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/cache-machine.gemspec
CHANGED
@@ -1,21 +1,15 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
5
2
|
|
6
3
|
Gem::Specification.new do |s|
|
7
4
|
s.name = %q{cache-machine}
|
8
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
9
6
|
|
10
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
8
|
s.authors = ["Sergei Zinin", "Kevin Goslar"]
|
12
|
-
s.date = %q{
|
9
|
+
s.date = %q{2012-03-05}
|
13
10
|
s.description = %q{A Ruby on Rails framework to support cache management based on explicitely modeled caching dependencies.}
|
14
|
-
s.email = %q{
|
15
|
-
s.extra_rdoc_files =
|
16
|
-
"LICENSE.txt",
|
17
|
-
"README.rdoc"
|
18
|
-
]
|
11
|
+
s.email = %q{szinin@partyearth.com}
|
12
|
+
s.extra_rdoc_files = %w{LICENSE.txt README.md}
|
19
13
|
s.files = `git ls-files`.split("\n")
|
20
14
|
s.homepage = %q{http://github.com/partyearth/cache-machine}
|
21
15
|
s.licenses = ["MIT"]
|
@@ -27,23 +21,14 @@ Gem::Specification.new do |s|
|
|
27
21
|
s.specification_version = 3
|
28
22
|
|
29
23
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
30
|
-
s.add_runtime_dependency(%q<rails>, [">=
|
31
|
-
s.add_runtime_dependency(%q<activemodel>, [">= 0"])
|
32
|
-
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
24
|
+
s.add_runtime_dependency(%q<rails>, [">= 3"])
|
33
25
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
34
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
|
35
26
|
else
|
36
|
-
s.add_dependency(%q<rails>, [">=
|
37
|
-
s.add_dependency(%q<activemodel>, [">= 0"])
|
38
|
-
s.add_dependency(%q<activesupport>, [">= 0"])
|
27
|
+
s.add_dependency(%q<rails>, [">= 3"])
|
39
28
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
40
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
41
29
|
end
|
42
30
|
else
|
43
|
-
s.add_dependency(%q<rails>, [">=
|
44
|
-
s.add_dependency(%q<activemodel>, [">= 0"])
|
45
|
-
s.add_dependency(%q<activesupport>, [">= 0"])
|
31
|
+
s.add_dependency(%q<rails>, [">= 3"])
|
46
32
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
47
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
48
33
|
end
|
49
34
|
end
|
data/db/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.*db
|
data/lib/cache-machine.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (c) 2011 {PartyEarth LLC}[http://partyearth.com]
|
3
|
-
# mailto:
|
3
|
+
# mailto:szinin@partyearth.com
|
4
4
|
#++
|
5
|
+
require "cache_machine/cache/scope"
|
6
|
+
require "cache_machine/cache/timestamp_builder"
|
7
|
+
require "cache_machine/cache/associations"
|
8
|
+
require "cache_machine/cache/mapper"
|
5
9
|
require "cache_machine/cache"
|
6
10
|
require "cache_machine/helpers/cache_helper"
|
7
11
|
require "cache_machine/logger"
|
8
12
|
require "cache_machine/railtie"
|
9
13
|
|
10
|
-
ActiveRecord::Base.send :include, CacheMachine::Cache
|
14
|
+
ActiveRecord::Base.send :include, CacheMachine::Cache
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module CacheMachine
|
2
|
+
require "cache_machine/logger"
|
3
|
+
|
4
|
+
# API to your cache storage.
|
5
|
+
class Adapter
|
6
|
+
|
7
|
+
def initialize(*options)
|
8
|
+
raise 'not implemented yet'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Appends an id to map of associations.
|
12
|
+
#
|
13
|
+
# @param target ActiveRecord object
|
14
|
+
# @param [ String, Symbol ] association Name of an association from target
|
15
|
+
# @param id Uniq identifier of any member from association of target
|
16
|
+
def append_id_to_map(target, association, id)
|
17
|
+
raise 'not implemented yet'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Appends an id to map of associations in reverse-direction to used association.
|
21
|
+
#
|
22
|
+
# @param [ Class ] resource
|
23
|
+
# @param [ String, Symbol ] association Name of an association from target
|
24
|
+
# @param target
|
25
|
+
# @param id Uniq identifier of any member having class _resource_ of target association
|
26
|
+
def append_id_to_reverse_map(resource, association, target, id)
|
27
|
+
raise 'not implemented yet'
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns ids from cache.
|
31
|
+
#
|
32
|
+
# @param target
|
33
|
+
# @param [ String, Symbol ] association Collection name where we fetch ids.
|
34
|
+
#
|
35
|
+
# @return [ Array ]
|
36
|
+
def association_ids(target, association)
|
37
|
+
raise 'not implemented yet'
|
38
|
+
end
|
39
|
+
|
40
|
+
# Deletes key in cache.
|
41
|
+
#
|
42
|
+
# @param key
|
43
|
+
def delete(key)
|
44
|
+
raise 'not implemented yet'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Deletes content from cache.
|
48
|
+
#
|
49
|
+
# @param key
|
50
|
+
def delete_content(key)
|
51
|
+
raise 'not implemented yet'
|
52
|
+
end
|
53
|
+
|
54
|
+
# Fetches cache.
|
55
|
+
#
|
56
|
+
# @param key
|
57
|
+
# @param [ Hash ] options
|
58
|
+
#
|
59
|
+
# @return [ Object ]
|
60
|
+
def fetch(key, options = {}, &block)
|
61
|
+
raise 'not implemented yet'
|
62
|
+
end
|
63
|
+
|
64
|
+
# Fetches timestamp from cache.
|
65
|
+
#
|
66
|
+
# @param [ String, Symbol ] name
|
67
|
+
# @param [ Hash ] options
|
68
|
+
#
|
69
|
+
# @return [ String ]
|
70
|
+
def fetch_timestamp(name, options = {}, &block)
|
71
|
+
raise 'not implemented yet'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns content key used for fetch blocks.
|
75
|
+
#
|
76
|
+
# @param [ String, Symbol ] key
|
77
|
+
#
|
78
|
+
# @return String
|
79
|
+
def get_content_key(key)
|
80
|
+
"Content##{key}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns key used for associations map.
|
84
|
+
#
|
85
|
+
# @param target
|
86
|
+
# @param [ String, Symbol ] association
|
87
|
+
#
|
88
|
+
# @return String
|
89
|
+
def get_map_key(target, association)
|
90
|
+
"Map##{target.class.name}|#{target.send(target.class.primary_key)}|#{association}"
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns key to fetch timestamp from cache.
|
94
|
+
#
|
95
|
+
# @param [ String, Symbol ] name
|
96
|
+
#
|
97
|
+
# @return String
|
98
|
+
def get_timestamp_key(name)
|
99
|
+
"Timestamp##{name}"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns key used for reversed associations map.
|
103
|
+
#
|
104
|
+
# @param [ Class ] resource
|
105
|
+
# @param [ String, Symbol ] association
|
106
|
+
# @param target
|
107
|
+
#
|
108
|
+
# @return String
|
109
|
+
def get_reverse_map_key(resource, association, target)
|
110
|
+
"ReverseMap##{resource}|#{target.send(target.class.primary_key)}|#{association}"
|
111
|
+
end
|
112
|
+
|
113
|
+
# Resets timestamp by name.
|
114
|
+
#
|
115
|
+
# @param [ String, Symbol ] name
|
116
|
+
def reset_timestamp(name)
|
117
|
+
raise 'not implemented yet'
|
118
|
+
end
|
119
|
+
|
120
|
+
# Writes timestamp in cache.
|
121
|
+
#
|
122
|
+
# @param [ String, Symbol ] name
|
123
|
+
def write_timestamp(name, &block)
|
124
|
+
raise 'not implemented yet'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|