active_model_cachers 2.1.4 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +76 -52
- data/lib/active_model_cachers.rb +11 -0
- data/lib/active_model_cachers/active_record/extension.rb +14 -13
- data/lib/active_model_cachers/active_record/global_callbacks.rb +16 -8
- data/lib/active_model_cachers/cache_service.rb +16 -6
- data/lib/active_model_cachers/column_value_cache.rb +2 -1
- data/lib/active_model_cachers/hook/on_model_delete.rb +2 -2
- data/lib/active_model_cachers/{active_record → patches}/patch_rails_3.rb +0 -0
- data/lib/active_model_cachers/patches/uninitialized_attribute.rb +9 -0
- data/lib/active_model_cachers/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a8f59a55915fa875ecfda9692094c2054e434349b847e2abfd11b030e0dfee8
|
4
|
+
data.tar.gz: b1e594fb44ab1248cc10b54daca3149d1abb0f35cef902a6982e51a14251ac61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67c437185d13326f655820d9950f81bf9109470b2aab4e128554525af7710c0048d3fda5d1341fcd128a55fcf153ec30d99e77223d68a9f385a2e68c58c98636
|
7
|
+
data.tar.gz: 6c66961a17577c16afabbb80bc8a6920ca256355d096d35cd518d054a284ac36d4b6679ca038d82b52bab19338c9df21057dccaa341d5f5f2804af52c76af8a5
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
## Change Log
|
2
2
|
|
3
|
+
### [v2.1.4](https://github.com/khiav223577/active_model_cachers/compare/v2.1.3...v2.1.4) 2018/06/14
|
4
|
+
- [#41](https://github.com/khiav223577/active_model_cachers/pull/41) Fix: binding problem (@khiav223577)
|
5
|
+
- [#40](https://github.com/khiav223577/active_model_cachers/pull/40) [Refactor] Solve warnings (@khiav223577)
|
6
|
+
|
3
7
|
### [v2.1.3](https://github.com/khiav223577/active_model_cachers/compare/v2.1.2...v2.1.3) 2018/06/07
|
4
8
|
- [#38](https://github.com/khiav223577/active_model_cachers/pull/38) Fix: Eager-loaded models will not register `after_commit` callback (@khiav223577)
|
5
9
|
|
data/README.md
CHANGED
@@ -6,35 +6,50 @@
|
|
6
6
|
[![Code Climate](https://codeclimate.com/github/khiav223577/active_model_cachers/badges/gpa.svg)](https://codeclimate.com/github/khiav223577/active_model_cachers)
|
7
7
|
[![Test Coverage](https://codeclimate.com/github/khiav223577/active_model_cachers/badges/coverage.svg)](https://codeclimate.com/github/khiav223577/active_model_cachers/coverage)
|
8
8
|
|
9
|
-
|
9
|
+
ActiveModelCachers provides cachers to models and allows the users to specify what needs to be cached. The data will be cached at `Rails.cache` and also at application level via `RequestStore`, to cache values between requests. The cachers will maintain cached objects and expire them when they are changed (e.g. created, updated, destroyed, or deleted).
|
10
10
|
|
11
|
-
|
12
|
-
- Do not pollute original ActiveModel API.
|
13
|
-
- Support ActiveRecord 3, 4, 5.
|
14
|
-
- High test coverage
|
11
|
+
ActiveModelCachers:
|
15
12
|
|
13
|
+
- Uses multiple levels of cache ([Multi-level Cache](#multi-level-cache))
|
14
|
+
- Does not pollute the original ActiveModel API
|
15
|
+
- Supports ActiveRecord 3, 4 and 5
|
16
|
+
- Has high test coverage
|
17
|
+
|
18
|
+
### Table of contents
|
19
|
+
|
20
|
+
1. [Compare with identity_cache](#compare-with-identity_cache)
|
21
|
+
2. [Installation](#installation)
|
22
|
+
3. [Usage](#usage)
|
23
|
+
4. [Examples](#examples)
|
24
|
+
5. [Smart Caching](#smart-caching)
|
25
|
+
6. [Convenient syntax sugar for caching ActiveRecord](#convenient-syntax-sugar-for-caching-activerecord)
|
26
|
+
7. [Options](#options)
|
27
|
+
8. [Future Works](#future-works)
|
28
|
+
9. [Development](#development)
|
29
|
+
10. [Contributing](#contributing)
|
30
|
+
11. [License](#license)
|
16
31
|
|
17
32
|
## Compare with [identity_cache](https://github.com/Shopify/identity_cache)
|
18
33
|
|
19
|
-
`active_model_cachers` allows you to specify what to cache and when to expire those caches
|
34
|
+
`active_model_cachers` allows you to specify what to cache and when to expire those caches, so that you can cache raw sql query results, time-consuming methods, responses of requests, and so on. It also supports AR associations/attibutes (has_many, has_one, belongs_to) and secondary indexes.
|
20
35
|
|
21
|
-
`identity_cache` focuses on AR, and doesn't have the flexibility to specify the query
|
36
|
+
`identity_cache` focuses on AR, and doesn't have the flexibility to specify the query.`identity_cache` has more features for caching AR associations/attibutes. Some of these feature are: Caching attibutes by multiple keys, embedding associations to load data in one fetch, non-unique secondary indexes, and caching polymorphic associations.
|
22
37
|
|
23
|
-
|
38
|
+
Another important difference is that `active_model_cachers` encapsulates methods to `cacher`, while `identity_cache` adds a number of `fetch_*` method to `AR` directly, therefore it's more possible to have method name collision when using `identity_cache`.
|
24
39
|
|
25
40
|
## Installation
|
26
41
|
|
27
|
-
|
42
|
+
To install active_model_cachers, add this line to your application's Gemfile:
|
28
43
|
|
29
44
|
```ruby
|
30
45
|
gem 'active_model_cachers'
|
31
46
|
```
|
32
47
|
|
33
|
-
|
48
|
+
Then execute:
|
34
49
|
|
35
50
|
$ bundle
|
36
51
|
|
37
|
-
Or install it yourself
|
52
|
+
Or install it yourself by executing:
|
38
53
|
|
39
54
|
$ gem install active_model_cachers
|
40
55
|
|
@@ -48,19 +63,20 @@ end
|
|
48
63
|
|
49
64
|
## Usage
|
50
65
|
|
51
|
-
###
|
66
|
+
### The `cache_at` method
|
67
|
+
|
68
|
+
Use the `cache_at` method to cache whatever you want. Specify a cache on the model:
|
52
69
|
|
53
70
|
`cache_at(name, query = nil, options = {})`
|
54
71
|
|
55
|
-
|
56
|
-
- name: the attribute name
|
57
|
-
- query: how to get data on cache miss. It will be set automatically if the name
|
72
|
+
Parameters:
|
73
|
+
- name: the attribute name
|
74
|
+
- query: how to get data on cache miss. It will be set automatically if the name matches an association or an attribute.
|
58
75
|
- options: see [here](#options)
|
59
76
|
|
60
|
-
###
|
61
|
-
|
62
|
-
The `cacher` is defined as `class method` and `instance method` of Model. You could call the method and get the cacher instance, e.g. `User.cacher` or `user.cacher`. An attribute will define a method on cacher, cached attributes are asscessable via it, e.g. `user.cacher.the_attribute_name`.
|
77
|
+
### Access the cached attributes
|
63
78
|
|
79
|
+
"To avoid method name collision, all methods will be defined on the `Cacher` instead of `ActiveModel`. You can get the `cacher` from the class or from the instance (e.g. `User.cacher` or `user.cacher`), then access cached attributes via the method defined by `cache_at` (e.g. `user.cacher.the_attribute_name`)."
|
64
80
|
|
65
81
|
### Basic Example
|
66
82
|
```rb
|
@@ -74,10 +90,8 @@ user.cacher.something_you_want_to_cache
|
|
74
90
|
|
75
91
|
## Examples
|
76
92
|
|
77
|
-
### Example 1: Cache the number of active
|
78
|
-
|
79
|
-
After specifying the name as `active_count` and how to get data when cache miss by lambda `User.active.count`.
|
80
|
-
You could access the cached data by calling `active_count` method on the cacher, `User.cacher`.
|
93
|
+
### Example 1: Cache the number of active users
|
94
|
+
Specify the method name as `active_count`. After using lambda `User.active.count` to define how the data can be accessed when there is a cache miss, you can get the cached data by calling `active_count` method on the cacher `User.cacher`.
|
81
95
|
|
82
96
|
```rb
|
83
97
|
class User < ActiveRecord::Base
|
@@ -88,11 +102,11 @@ end
|
|
88
102
|
@count = User.cacher.active_count
|
89
103
|
```
|
90
104
|
|
91
|
-
You may want to flush cache on the number of active
|
105
|
+
You may want to flush cache on the number of active users changed. It can be done by setting [`expire_by`](#expire_by). In this case, `User#last_login_at` means flushing the cache when a user's `last_login_at` is changed (by save, update, create, destroy or delete).
|
92
106
|
|
93
|
-
### Example 2: Cache the number of
|
107
|
+
### Example 2: Cache the number of users
|
94
108
|
|
95
|
-
In this example, the cache should be cleaned on user `destroyed`, or new user `created`, but not on user `updated`. You
|
109
|
+
In this example, the cache should be cleaned on user `destroyed`, or new user `created`, but not on user `updated`. You can specify the cleaning callback to only fire on certain events by [`on`](#on).
|
96
110
|
|
97
111
|
```rb
|
98
112
|
class User < ActiveRecord::Base
|
@@ -104,7 +118,7 @@ end
|
|
104
118
|
|
105
119
|
### Example 3: Access the cacher from a model instance
|
106
120
|
|
107
|
-
You could use the cacher from instance scope, e.g. `user.cacher`, instead of `User.cacher`. The difference is that the `binding` of query lambda is changed. In this example, you
|
121
|
+
You could use the cacher from the instance scope, e.g. `user.cacher`, instead of `User.cacher`. The difference is that the `binding` of query lambda is changed. In this example, you can write the query as `posts.exists?` which is in instance scope. The binding of the lambda is `user`, not `User`, so that it accesses `posts` method of `user`.
|
108
122
|
|
109
123
|
```rb
|
110
124
|
class User < ActiveRecord::Base
|
@@ -115,12 +129,12 @@ end
|
|
115
129
|
do_something if current_user.cacher.has_post?
|
116
130
|
```
|
117
131
|
|
118
|
-
In this example, the cache should be cleaned when the `posts` of the user changed.
|
132
|
+
In this example, the cache should be cleaned when the `posts` of the user is changed. If you set `expire_by` to the association: `:posts`, it will do all the work for you (It actually sets [`expire_by`](#expire_by) to `Post#user_id` and [`foreign_key`](#foreign_key), which is needed for backtracing the user id from post, to `:user_id`).
|
119
133
|
|
120
134
|
|
121
|
-
### Example 4: Pass an argument to the query lambda
|
135
|
+
### Example 4: Pass an argument to the query lambda
|
122
136
|
|
123
|
-
You
|
137
|
+
You can also cache the result of outer service.`email_valid?` doesn't match an association or an attribute, so by default, the cache will not be cleaned by any changes.
|
124
138
|
|
125
139
|
```rb
|
126
140
|
class User < ActiveRecord::Base
|
@@ -130,7 +144,7 @@ end
|
|
130
144
|
render_error if not User.cacher_at('pearl@example.com').email_valid?
|
131
145
|
```
|
132
146
|
|
133
|
-
The query lambda can have one parameter
|
147
|
+
The query lambda can have one parameter. You can pass variable to it by using `cacher_at`. For example, `User.cacher_at(email)`.
|
134
148
|
|
135
149
|
```rb
|
136
150
|
class User < ActiveRecord::Base
|
@@ -140,11 +154,11 @@ end
|
|
140
154
|
render_error if not current_user.cacher.email_valid?
|
141
155
|
```
|
142
156
|
|
143
|
-
|
157
|
+
The query lambda can also be accessed from instance cacher, but you have to set [`primary_key`](#primary_key). The primary key specifies which attribute should be passed to the parameter.
|
144
158
|
|
145
159
|
### Example 5: Store all data in hash
|
146
160
|
|
147
|
-
Sometimes you may need to query multiple objects. Although the query results will be cached, the application still needs to query the cache server multiple times. If one communication
|
161
|
+
Sometimes you may need to query multiple objects. Although the query results will be cached, the application still needs to query the cache server multiple times. If one communication takes 0.1 ms, 1000 communications will take 100ms! For example:
|
148
162
|
|
149
163
|
```rb
|
150
164
|
class Skill < ActiveRecord::Base
|
@@ -155,7 +169,7 @@ end
|
|
155
169
|
@attack = skill_ids.inject(0){|sum, id| sum + Skill.cacher_at(id).atk_power }
|
156
170
|
```
|
157
171
|
|
158
|
-
One
|
172
|
+
One solution is to store a lookup table into the cache, so that only one cache object is stored. This will allow you to retrieve all of the needed data in one query.
|
159
173
|
|
160
174
|
```rb
|
161
175
|
class Skill < ActiveRecord::Base
|
@@ -168,7 +182,7 @@ end
|
|
168
182
|
|
169
183
|
### Example 6: Clean the cache manually
|
170
184
|
|
171
|
-
Sometimes it
|
185
|
+
Sometimes it is necessary to maintain the cache manually (For example, after calling `update_all`, `delete_all` or `import` records without calling callbacks).
|
172
186
|
|
173
187
|
```rb
|
174
188
|
class User < ActiveRecord::Base
|
@@ -188,7 +202,7 @@ User.cacher_at(user_id).clean_profile
|
|
188
202
|
|
189
203
|
### Example 7: Peek the data stored in cache
|
190
204
|
|
191
|
-
If you
|
205
|
+
If you only want to check the cached objects, but don't want it to load them from the database automatically when there is no cache, you can use `peek` method on `cacher`.
|
192
206
|
|
193
207
|
```rb
|
194
208
|
class User < ActiveRecord::Base
|
@@ -210,16 +224,16 @@ User.cacher_at(user_id).peek_profile
|
|
210
224
|
## Smart Caching
|
211
225
|
|
212
226
|
### Multi-level Cache
|
213
|
-
There is multi-level cache in order to
|
227
|
+
There is multi-level cache in order to increase the speed of data access.
|
214
228
|
|
215
229
|
1. RequestStore
|
216
230
|
2. Rails.cache
|
217
231
|
3. Association Cache
|
218
232
|
4. Database
|
219
233
|
|
220
|
-
`RequestStore` is used to make sure same object will not loaded from cache twice, since the data transfer between `Cache` and `Application`
|
234
|
+
`RequestStore` is used to make sure the same object will not be loaded from cache twice, since the data transfer between `Cache` and `Application` consumes time.
|
221
235
|
|
222
|
-
`Association Cache`
|
236
|
+
`Association Cache` prevents preloaded objects being loaded again.
|
223
237
|
|
224
238
|
For example:
|
225
239
|
```rb
|
@@ -244,7 +258,7 @@ end
|
|
244
258
|
|
245
259
|
### Caching Self
|
246
260
|
|
247
|
-
Cache self by id
|
261
|
+
Cache self by id:
|
248
262
|
```rb
|
249
263
|
class User < ActiveRecord::Base
|
250
264
|
cache_self
|
@@ -259,7 +273,7 @@ User.cacher.peek_by(id: user_id)
|
|
259
273
|
User.cacher.clean_by(id: user_id)
|
260
274
|
```
|
261
275
|
|
262
|
-
Also support caching self by other columns
|
276
|
+
Also support caching self by other columns:
|
263
277
|
```rb
|
264
278
|
class User < ActiveRecord::Base
|
265
279
|
cache_self by: :account
|
@@ -288,17 +302,23 @@ end
|
|
288
302
|
|
289
303
|
### :expire_by
|
290
304
|
|
291
|
-
Monitor on the specific model. Clean the cached objects if
|
305
|
+
Monitor on the specific model. Clean the cached objects if targets are changed.
|
292
306
|
|
293
|
-
-
|
307
|
+
- If empty, e.g. `nil` or `''`: Monitoring nothing.
|
294
308
|
|
295
|
-
-
|
309
|
+
- If string, e.g. `User`: Monitoring all attributes of `User`.
|
296
310
|
|
297
|
-
-
|
311
|
+
- If string with keyword `#`, e.g. `User#last_login_in_at`: Monitoring only an specific attribute.
|
298
312
|
|
299
|
-
-
|
313
|
+
- If symbol, e.g. `:posts`: Monitoring on the association. It will monitor all attributes of `Post` and set the `foreign_key'.
|
300
314
|
|
301
|
-
-
|
315
|
+
- The default value depends on the `name`. If `name`:
|
316
|
+
|
317
|
+
- Is an association, monitoring the association klass
|
318
|
+
|
319
|
+
- Is an attribute, monitoring current klass and the attribute name
|
320
|
+
|
321
|
+
- In other cases, monitoring nothing
|
302
322
|
|
303
323
|
### :on
|
304
324
|
|
@@ -316,17 +336,21 @@ Monitor on the specific model. Clean the cached objects if target are changed.
|
|
316
336
|
|
317
337
|
### :foreign_key
|
318
338
|
|
319
|
-
|
339
|
+
- Is needed only for caching assoication
|
340
|
+
|
341
|
+
- Does not need to be set if [`expire_by`](#expire_by) is set to monitor association.
|
342
|
+
|
343
|
+
- Is used for backtracing the cache key from cached objects. For example, it is used if `user` has_many `posts`, and `posts` is cached by user.id. If the post is changed, the column it is going to target must be specified so that the post can clean the cache at user (In this example mentioned, the column was `user_id`).
|
320
344
|
|
321
|
-
|
345
|
+
- Has the default value `:id`.
|
322
346
|
|
323
|
-
|
347
|
+
- Will be automatically determined if [`expire_by`](#expire_by) is symbol
|
324
348
|
|
325
349
|
### :primary_key
|
326
350
|
|
327
|
-
|
351
|
+
- Is needed to know which attribute should be passed to the parameter when using the instance `cacher`. For example, if a query, named `email_valid?`, uses `user.email` as parameter, and you call it from instance: `user.cacher.email_valid?`, pass `user.id` as the argument.
|
328
352
|
|
329
|
-
|
353
|
+
- Has the default value `:id`.
|
330
354
|
|
331
355
|
## Future works
|
332
356
|
|
@@ -341,7 +365,7 @@ This option is needed to know which attribute should be passed to the parameter
|
|
341
365
|
|
342
366
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
343
367
|
|
344
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb
|
368
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb` before running `bundle exec rake release` (This command will create a git tag for the version, push the git commits, tags and the `.gem` files to rubygems.org).
|
345
369
|
|
346
370
|
## Contributing
|
347
371
|
|
data/lib/active_model_cachers.rb
CHANGED
@@ -15,3 +15,14 @@ module ActiveModelCachers
|
|
15
15
|
end
|
16
16
|
|
17
17
|
ActiveRecord::Base.send(:extend, ActiveModelCachers::ActiveRecord::Extension)
|
18
|
+
|
19
|
+
gem_version = Gem::Version.new(ActiveRecord::VERSION::STRING)
|
20
|
+
if gem_version < Gem::Version.new('4')
|
21
|
+
require 'active_model_cachers/patches/patch_rails_3'
|
22
|
+
end
|
23
|
+
|
24
|
+
# https://github.com/rails/rails/pull/29018
|
25
|
+
if gem_version >= Gem::Version.new('5') && gem_version < Gem::Version.new('5.2')
|
26
|
+
require 'active_model_cachers/patches/uninitialized_attribute'
|
27
|
+
end
|
28
|
+
|
@@ -85,22 +85,23 @@ module ActiveModelCachers
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
@global_callbacks =
|
88
|
+
@global_callbacks = nil
|
89
89
|
def self.global_callbacks
|
90
|
-
@global_callbacks
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
90
|
+
if @global_callbacks == nil
|
91
|
+
global_callbacks = @global_callbacks = GlobalCallbacks.new
|
92
|
+
::ActiveRecord::Base.instance_exec do
|
93
|
+
after_commit ->{
|
94
|
+
global_callbacks.after_commit1.exec(self, self.class)
|
95
|
+
global_callbacks.after_commit2.exec(self, self.class)
|
96
|
+
}
|
97
|
+
after_touch ->{
|
98
|
+
global_callbacks.after_touch1.exec(self, self.class)
|
99
|
+
global_callbacks.after_touch2.exec(self, self.class)
|
100
|
+
}
|
101
|
+
end
|
98
102
|
end
|
103
|
+
return @global_callbacks
|
99
104
|
end
|
100
105
|
end
|
101
106
|
end
|
102
107
|
end
|
103
|
-
|
104
|
-
if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4')
|
105
|
-
require 'active_model_cachers/active_record/patch_rails_3'
|
106
|
-
end
|
@@ -5,12 +5,12 @@ module ActiveModelCachers
|
|
5
5
|
@type_callbacks = {}
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
define_callbacks(:
|
8
|
+
def before_delete1(class_name = nil, &block)
|
9
|
+
define_callbacks(:before_delete1, class_name, &block)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
define_callbacks(:
|
12
|
+
def before_delete2(class_name = nil, &block)
|
13
|
+
define_callbacks(:before_delete2, class_name, &block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def after_delete(class_name = nil, &block)
|
@@ -21,12 +21,20 @@ module ActiveModelCachers
|
|
21
21
|
define_callbacks(:on_nullify, class_name, &block)
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
define_callbacks(:
|
24
|
+
def after_commit1(class_name = nil, &block)
|
25
|
+
define_callbacks(:after_commit1, class_name, &block)
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
define_callbacks(:
|
28
|
+
def after_commit2(class_name = nil, &block)
|
29
|
+
define_callbacks(:after_commit2, class_name, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def after_touch1(class_name = nil, &block)
|
33
|
+
define_callbacks(:after_touch1, class_name, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def after_touch2(class_name = nil, &block)
|
37
|
+
define_callbacks(:after_touch2, class_name, &block)
|
30
38
|
end
|
31
39
|
|
32
40
|
private
|
@@ -32,21 +32,31 @@ module ActiveModelCachers
|
|
32
32
|
get_ids.call.each{|s| clean.call(s) } if nullified_column == column
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
clean.call(
|
35
|
+
after_touch1(class_name) do
|
36
|
+
clean.call(@@column_value_cache.add(self.class, class_name, id, foreign_key, self).call)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
after_touch2(class_name) do
|
40
|
+
@@column_value_cache.clean_cache
|
41
|
+
end
|
42
|
+
|
43
|
+
after_commit1(class_name) do
|
40
44
|
next if fire_on and not transaction_include_any_action?(fire_on)
|
41
45
|
changed = column ? previous_changes.key?(column) : previous_changes.present?
|
42
|
-
|
46
|
+
if changed || destroyed?
|
47
|
+
clean.call(@@column_value_cache.add(self.class, class_name, id, foreign_key, self).call)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
after_commit2(class_name) do
|
52
|
+
@@column_value_cache.clean_cache
|
43
53
|
end
|
44
54
|
|
45
|
-
|
55
|
+
before_delete1(class_name) do |id, model|
|
46
56
|
clean_ids << @@column_value_cache.add(self, class_name, id, foreign_key, model)
|
47
57
|
end
|
48
58
|
|
49
|
-
|
59
|
+
before_delete2(class_name) do |_, model|
|
50
60
|
clean_ids.each{|s| clean.call(s.call) }
|
51
61
|
clean_ids = []
|
52
62
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
class ActiveModelCachers::ColumnValueCache
|
3
4
|
def initialize
|
4
5
|
@cache1 = Hash.new{|h, k| h[k] = {} }
|
@@ -40,7 +41,7 @@ class ActiveModelCachers::ColumnValueCache
|
|
40
41
|
def get_id_from(object, id, column, model)
|
41
42
|
return id if column == 'id'
|
42
43
|
model ||= object.cacher.peek_by(id: id) if object.has_cacher?
|
43
|
-
return model.send(column) if model
|
44
|
+
return model.send(column) if model and model.has_attribute?(column)
|
44
45
|
return :not_set
|
45
46
|
end
|
46
47
|
end
|
@@ -13,8 +13,8 @@ module ActiveModelCachers::Hook
|
|
13
13
|
|
14
14
|
module ClassMethods
|
15
15
|
def delete(id, model = nil)
|
16
|
-
ActiveModelCachers::ActiveRecord::Extension.global_callbacks.
|
17
|
-
ActiveModelCachers::ActiveRecord::Extension.global_callbacks.
|
16
|
+
ActiveModelCachers::ActiveRecord::Extension.global_callbacks.before_delete1.exec(self, self, id, model)
|
17
|
+
ActiveModelCachers::ActiveRecord::Extension.global_callbacks.before_delete2.exec(self, self, id, model)
|
18
18
|
|
19
19
|
result = super(id)
|
20
20
|
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_model_cachers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- khiav reoy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,7 +122,6 @@ files:
|
|
122
122
|
- lib/active_model_cachers/active_record/cacher.rb
|
123
123
|
- lib/active_model_cachers/active_record/extension.rb
|
124
124
|
- lib/active_model_cachers/active_record/global_callbacks.rb
|
125
|
-
- lib/active_model_cachers/active_record/patch_rails_3.rb
|
126
125
|
- lib/active_model_cachers/cache_service.rb
|
127
126
|
- lib/active_model_cachers/cache_service_factory.rb
|
128
127
|
- lib/active_model_cachers/column_value_cache.rb
|
@@ -132,6 +131,8 @@ files:
|
|
132
131
|
- lib/active_model_cachers/hook/dependencies.rb
|
133
132
|
- lib/active_model_cachers/hook/on_model_delete.rb
|
134
133
|
- lib/active_model_cachers/nil_object.rb
|
134
|
+
- lib/active_model_cachers/patches/patch_rails_3.rb
|
135
|
+
- lib/active_model_cachers/patches/uninitialized_attribute.rb
|
135
136
|
- lib/active_model_cachers/version.rb
|
136
137
|
homepage: https://github.com/khiav223577/active_model_cachers
|
137
138
|
licenses:
|