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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d62a0b3c3456a59bd79c3df098c46c6259d6683576714d0744671ab397f6ae27
4
- data.tar.gz: e8608849cdb7f0eb50f83c8a19a95c106c88e3d4a5e3ea1155bcedbcde6c4770
3
+ metadata.gz: 3a8f59a55915fa875ecfda9692094c2054e434349b847e2abfd11b030e0dfee8
4
+ data.tar.gz: b1e594fb44ab1248cc10b54daca3149d1abb0f35cef902a6982e51a14251ac61
5
5
  SHA512:
6
- metadata.gz: 0ea2eaaba63a07e27354f60f8a2790269da1fb6b2208eb6a05f1c7b0b24cffc51dcd0c593c197b9c20af26c041fbfb0c8eca8e18600468daad90ee47b6ea3b10
7
- data.tar.gz: 8ac03f042b17d41c265fb861f7c602651df02691780c1779d9441eb906efb9fac2d89791b83e3f1daf33717aab8b35c9b4223ffa3ecc076ecfe1cc356953e56e
6
+ metadata.gz: 67c437185d13326f655820d9950f81bf9109470b2aab4e128554525af7710c0048d3fda5d1341fcd128a55fcf153ec30d99e77223d68a9f385a2e68c58c98636
7
+ data.tar.gz: 6c66961a17577c16afabbb80bc8a6920ca256355d096d35cd518d054a284ac36d4b6679ca038d82b52bab19338c9df21057dccaa341d5f5f2804af52c76af8a5
@@ -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
- Provide cachers to the model so that you could specify which you want to cache. Data will be cached at `Rails.cache` and also at application level via `RequestStore` to cache values between requests. Cachers will maintain cached objects and expire them when they are changed (including create, update, destroy, and even delete).
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
- - [Multi-level Cache](#multi-level-cache)
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. So that you could 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.
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. It has more features for caching AR associations / attibutes, such as caching attibutes by multiple keys, embedding associations to load data in one fetch, non-unique secondary indexes, and caching polymorphic associations, etc.
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
- There is also a difference worths mentioning, `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.
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
- Add this line to your application's Gemfile:
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
- And then execute:
48
+ Then execute:
34
49
 
35
50
  $ bundle
36
51
 
37
- Or install it yourself as:
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
- ### Cache whatever you want by `cache_at` method
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
- Specify a cache on the model.
56
- - name: the attribute name.
57
- - query: how to get data on cache miss. It will be set automatically if the name match an association or an attribute.
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
- ### Asscess the cached attributes
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 user
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 user changed. It can be done by simply 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 (whenever by save, update, create, destroy or delete).
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 user
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 could specify the cleaning callback to only fire on certain events by [`on`](#on).
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 could write the query as `posts.exists?` in that it's in instance scope, and the binding of the lambda is `user`, not `User`. So that it accesses `posts` method of `user`.
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. You could just set `expire_by` to the association: `:posts`, and then it will do all the works for you magically. (If you want know more details, it actually set [`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`)
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 could cache not only the query result of database but also the result of outer service. Becasue `email_valid?` doesn't match an association or an attribute, by default, the cache will not be cleaned by any changes.
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, you could pass variable to it by using `cacher_at`. For example, `User.cacher_at(email)`.
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
- It can also be accessed from instance cacher. But you have to set [`primary_key`](#primary_key), which is needed to know which attribute should be passed to the parameter.
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 take 0.1 ms, 1000 communications will take 100ms! For example:
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 of the solution is that you could store a lookup table into cache, so that only one cache object is stored and you can retrieve all of the needed data in one query.
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 needs to maintain the cache manually. For example, after calling `update_all`, `delete_all` or `import` records without calling callbacks.
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 just want to check the cached objects, but don't want it to load from database automatically when there is no cache. You could use `peek` method on `cacher`.
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 make the speed of data access go faster.
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` still consumes time.
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` will be used to prevent preloaded objects being loaded again.
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 target are changed.
305
+ Monitor on the specific model. Clean the cached objects if targets are changed.
292
306
 
293
- - if empty, e.g. `nil` or `''`: Monitoring nothing.
307
+ - If empty, e.g. `nil` or `''`: Monitoring nothing.
294
308
 
295
- - if string, e.g. `User`: Monitoring all attributes of `User`.
309
+ - If string, e.g. `User`: Monitoring all attributes of `User`.
296
310
 
297
- - if string with keyword `#`, e.g. `User#last_login_in_at`: Monitoring only the specific attribute.
311
+ - If string with keyword `#`, e.g. `User#last_login_in_at`: Monitoring only an specific attribute.
298
312
 
299
- - if symbol, e.g. `:posts`: Monitoring on the association. It will trying to do all the things for you, including monitoring all attributes of `Post` and set the `foreign_key`.
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
- - Default value depends on the `name`. If is an association, monitoring the association klass. If is an attribute, monitoring current klass and the attrribute name. If others, monitoring nothing.
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
- This option is needed only for caching assoication and need not to set if [`expire_by`](#expire_by) is set to monitor association. Used for backtracing the cache key from cached objects. For examle, if `user` has_many `posts`, and cached the `posts` by user.id. When a post is changed, it needs to know which column to use (in this example, `user_id`) to clean the cache at user.
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
- - Default value is `:id`
345
+ - Has the default value `:id`.
322
346
 
323
- - Will be automatically determined if [`expire_by`](#expire_by) is symbol.
347
+ - Will be automatically determined if [`expire_by`](#expire_by) is symbol
324
348
 
325
349
  ### :primary_key
326
350
 
327
- This option is needed to know which attribute should be passed to the parameter when you are using 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?`. You need to tell it to pass `user.email` instead of `user.id` as the argument.
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
- - Default value is `:id`
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`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
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
 
@@ -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 = GlobalCallbacks.new
88
+ @global_callbacks = nil
89
89
  def self.global_callbacks
90
- @global_callbacks
91
- end
92
-
93
- def self.extended(base)
94
- global_callbacks = @global_callbacks
95
- base.instance_exec do
96
- after_commit ->{ global_callbacks.after_commit.exec(self, self.class) }
97
- after_touch ->{ global_callbacks.after_touch.exec(self, self.class) }
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 pre_before_delete(class_name = nil, &block)
9
- define_callbacks(:pre_before_delete, class_name, &block)
8
+ def before_delete1(class_name = nil, &block)
9
+ define_callbacks(:before_delete1, class_name, &block)
10
10
  end
11
11
 
12
- def before_delete(class_name = nil, &block)
13
- define_callbacks(:before_delete, class_name, &block)
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 after_commit(class_name = nil, &block)
25
- define_callbacks(:after_commit, class_name, &block)
24
+ def after_commit1(class_name = nil, &block)
25
+ define_callbacks(:after_commit1, class_name, &block)
26
26
  end
27
27
 
28
- def after_touch(class_name = nil, &block)
29
- define_callbacks(:after_touch, class_name, &block)
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
- after_touch(class_name) do
36
- clean.call(send(foreign_key))
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
- after_commit(class_name) do # TODO: on
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
- clean.call(send(foreign_key)) if changed || destroyed?
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
- pre_before_delete(class_name) do |id, model|
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
- before_delete(class_name) do |_, model|
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.pre_before_delete.exec(self, self, id, model)
17
- ActiveModelCachers::ActiveRecord::Extension.global_callbacks.before_delete.exec(self, self, id, model)
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
 
@@ -0,0 +1,9 @@
1
+ if defined?(ActiveRecord::Attribute)
2
+ class ActiveRecord::Attribute
3
+ class Uninitialized < self
4
+ def forgetting_assignment
5
+ dup
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ActiveModelCachers
3
- VERSION = '2.1.4'
3
+ VERSION = '2.1.5'
4
4
  end
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
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-06-14 00:00:00.000000000 Z
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: