active_model_cachers 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +15 -11
- data/CHANGELOG.md +42 -0
- data/README.md +21 -8
- data/active_model_cachers.gemspec +2 -2
- data/gemfiles/3.2.gemfile +0 -1
- data/gemfiles/4.2.gemfile +0 -1
- data/gemfiles/5.0.gemfile +0 -1
- data/gemfiles/5.1.gemfile +0 -1
- data/gemfiles/5.2.gemfile +0 -1
- data/lib/active_model_cachers/active_record/extension.rb +4 -34
- data/lib/active_model_cachers/cache_service.rb +35 -0
- data/lib/active_model_cachers/cache_service_factory.rb +1 -0
- data/lib/active_model_cachers/version.rb +1 -1
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21afadb49c4f398b05f590e42e2d68dc972c4156601327aba48b218b5bfce70f
|
4
|
+
data.tar.gz: c25d240a1b3c891ee31a191f72d8540e282724cc0638e79c3089cc17ada31dfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75634a849304a07c250dae3d82d9ff9eb579873b976482de1987e01b28f5cf95878edf53e3b83bc5eb794e7e1f31bf537018299a4d93bf4ba083dc74b4063403
|
7
|
+
data.tar.gz: 1b05f797d94393b3d95a3b172a3276808f5bd6f3088d168698e2aa4ce55588aa6c1d58a62afbd29ab45ad9bb2c12d08c472aae0f718f549a5470d2a8e7af9256
|
data/.travis.yml
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
+
sudo: false
|
2
|
+
env:
|
3
|
+
global:
|
4
|
+
- CC_TEST_REPORTER_ID=02a53f73b72a95af756b1c0270d4b22a6f07d25a1c65048e341371e7b72671d9
|
1
5
|
language: ruby
|
2
6
|
rvm:
|
3
7
|
- 2.2
|
4
8
|
- 2.3
|
5
|
-
sudo: required
|
6
|
-
dist: trusty
|
7
|
-
before_install:
|
8
|
-
- gem install bundler
|
9
|
-
- gem update --system
|
10
|
-
- gem --version
|
11
9
|
gemfile:
|
12
10
|
- gemfiles/3.2.gemfile
|
13
11
|
- gemfiles/4.2.gemfile
|
14
12
|
- gemfiles/5.0.gemfile
|
15
13
|
- gemfiles/5.1.gemfile
|
16
14
|
- gemfiles/5.2.gemfile
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
-
|
15
|
+
before_install:
|
16
|
+
- gem install bundler
|
17
|
+
- gem update --system
|
18
|
+
- gem --version
|
19
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
20
|
+
- chmod +x ./cc-test-reporter
|
21
|
+
- ./cc-test-reporter before-build
|
22
|
+
script:
|
23
|
+
- bundle exec rake test
|
24
|
+
after_script:
|
25
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
22
26
|
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
## Change Log
|
2
|
+
|
3
|
+
### [v2.1.0](https://github.com/khiav223577/active_model_cachers/compare/v2.0.3...v2.1.0) 2018/05/18
|
4
|
+
- [#32](https://github.com/khiav223577/active_model_cachers/pull/32) Add test cases to test "store all data in hash" (@khiav223577)
|
5
|
+
- [#31](https://github.com/khiav223577/active_model_cachers/pull/31) Change the syntax of getting self from cache (@khiav223577)
|
6
|
+
- [#29](https://github.com/khiav223577/active_model_cachers/pull/29) test assigning association (@khiav223577)
|
7
|
+
|
8
|
+
### [v2.0.3](https://github.com/khiav223577/active_model_cachers/compare/v2.0.2...v2.0.3) 2018/05/14
|
9
|
+
- [#28](https://github.com/khiav223577/active_model_cachers/pull/28) No need to dump all association caches (@khiav223577)
|
10
|
+
|
11
|
+
### [v2.0.2](https://github.com/khiav223577/active_model_cachers/compare/v2.0.1...v2.0.2) 2018/05/14
|
12
|
+
- [#27](https://github.com/khiav223577/active_model_cachers/pull/27) [Fix] will send query even if has one association is cached (@khiav223577)
|
13
|
+
|
14
|
+
### [v2.0.1](https://github.com/khiav223577/active_model_cachers/compare/v2.0.0...v2.0.1) 2018/05/13
|
15
|
+
- [#26](https://github.com/khiav223577/active_model_cachers/pull/26) Prevent infinite loop if someone override default associations' method (@khiav223577)
|
16
|
+
|
17
|
+
### v2.0.0 2018/05/13
|
18
|
+
- [#25](https://github.com/khiav223577/active_model_cachers/pull/25) Support cache self by other column (@khiav223577)
|
19
|
+
- [#24](https://github.com/khiav223577/active_model_cachers/pull/24) Support cleaning the cache manually (@khiav223577)
|
20
|
+
- [#23](https://github.com/khiav223577/active_model_cachers/pull/23) use loaded model if possible to prevent extra queries (@khiav223577)
|
21
|
+
- [#22](https://github.com/khiav223577/active_model_cachers/pull/22) Support caching result from outer service (@khiav223577)
|
22
|
+
- [#21](https://github.com/khiav223577/active_model_cachers/pull/21) Support writing query in instance scope (@khiav223577)
|
23
|
+
- [#20](https://github.com/khiav223577/active_model_cachers/pull/20) instance cacher (@khiav223577)
|
24
|
+
- [#19](https://github.com/khiav223577/active_model_cachers/pull/19) Pass model to `delete` method to prevent an extra query (@khiav223577)
|
25
|
+
- [#18](https://github.com/khiav223577/active_model_cachers/pull/18) [Test] show all sql queries if query count doesn't equal to expected count. (@khiav223577)
|
26
|
+
- [#17](https://github.com/khiav223577/active_model_cachers/pull/17) Support cache at has_many association II - add test cases (@khiav223577)
|
27
|
+
- [#16](https://github.com/khiav223577/active_model_cachers/pull/16) Support cache at has_many association I (@khiav223577)
|
28
|
+
- [#15](https://github.com/khiav223577/active_model_cachers/pull/15) Adjust file structures (@khiav223577)
|
29
|
+
- [#14](https://github.com/khiav223577/active_model_cachers/pull/14) Support cache at belongs_to association (@khiav223577)
|
30
|
+
- [#13](https://github.com/khiav223577/active_model_cachers/pull/13) Fix that cache not cleaned if foreign_key is not `id` and calling `mode.delete` (@khiav223577)
|
31
|
+
- [#12](https://github.com/khiav223577/active_model_cachers/pull/12) [Refactor] move the active_record extension to proper directory (@khiav223577)
|
32
|
+
- [#11](https://github.com/khiav223577/active_model_cachers/pull/11) Fix id problem by specify foreign_key manually (@khiav223577)
|
33
|
+
- [#10](https://github.com/khiav223577/active_model_cachers/pull/10) cache on falsy result (@khiav223577)
|
34
|
+
- [#9](https://github.com/khiav223577/active_model_cachers/pull/9) Fix that all models cache with same id will be cleaned if any of one is cleaned (@khiav223577)
|
35
|
+
- [#8](https://github.com/khiav223577/active_model_cachers/pull/8) allow developer to specify whether the cache should expire (@khiav223577)
|
36
|
+
- [#7](https://github.com/khiav223577/active_model_cachers/pull/7) custom query which allow you to specify how to expire the cache by `expire_by` option (@khiav223577)
|
37
|
+
- [#6](https://github.com/khiav223577/active_model_cachers/pull/6) test cache self (@khiav223577)
|
38
|
+
- [#5](https://github.com/khiav223577/active_model_cachers/pull/5) Deal with delete, dependent: :delete that do not fire after_commit callback (@khiav223577)
|
39
|
+
- [#4](https://github.com/khiav223577/active_model_cachers/pull/4) split test cases to several files and refactor the code (@khiav223577)
|
40
|
+
- [#3](https://github.com/khiav223577/active_model_cachers/pull/3) Safer cache mechanism: Prevent cache from being left over if someone forgets to write `cache_self` (@khiav223577)
|
41
|
+
- [#2](https://github.com/khiav223577/active_model_cachers/pull/2) Adjust usage (@khiav223577)
|
42
|
+
- [#1](https://github.com/khiav223577/active_model_cachers/pull/1) use after_commit hook to expire cached associations (@khiav223577)
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
[](https://codeclimate.com/github/khiav223577/active_model_cachers)
|
7
7
|
[](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 (
|
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).
|
10
10
|
|
11
11
|
- [Multi-level Cache](#multi-level-cache)
|
12
12
|
- Do not pollute original ActiveModel API.
|
@@ -14,6 +14,14 @@ Provide cachers to the model so that you could specify which you want to cache.
|
|
14
14
|
- High test coverage
|
15
15
|
|
16
16
|
|
17
|
+
## Compare with [identity_cache](https://github.com/Shopify/identity_cache)
|
18
|
+
|
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.
|
20
|
+
|
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.
|
22
|
+
|
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.
|
24
|
+
|
17
25
|
## Installation
|
18
26
|
|
19
27
|
Add this line to your application's Gemfile:
|
@@ -74,7 +82,7 @@ You could access the cached data by calling `active_count` method on the cacher,
|
|
74
82
|
```rb
|
75
83
|
class User < ActiveRecord::Base
|
76
84
|
scope :active, ->{ where('last_login_at > ?', 7.days.ago) }
|
77
|
-
cache_at :active_count, ->{
|
85
|
+
cache_at :active_count, ->{ active.count }, expire_by: 'User#last_login_at'
|
78
86
|
end
|
79
87
|
|
80
88
|
@count = User.cacher.active_count
|
@@ -88,7 +96,7 @@ In this example, the cache should be cleaned on user `destroyed`, or new user `c
|
|
88
96
|
|
89
97
|
```rb
|
90
98
|
class User < ActiveRecord::Base
|
91
|
-
cache_at :count, ->{
|
99
|
+
cache_at :count, ->{ count }, expire_by: 'User', on: [:create, :destroy]
|
92
100
|
end
|
93
101
|
|
94
102
|
@count = User.cacher.count
|
@@ -151,7 +159,7 @@ One of the solution is that you could store a lookup table into cache, so that o
|
|
151
159
|
|
152
160
|
```rb
|
153
161
|
class Skill < ActiveRecord::Base
|
154
|
-
cache_at :atk_powers, ->{
|
162
|
+
cache_at :atk_powers, ->{ pluck(:id, :atk_power).to_h }, expire_by: 'Skill#atk_power'
|
155
163
|
end
|
156
164
|
|
157
165
|
# This will retrieve the data from cache servers only 1 times.
|
@@ -234,10 +242,6 @@ end
|
|
234
242
|
@profile = User.cacher_at(user_id).profile
|
235
243
|
```
|
236
244
|
|
237
|
-
### Caching Polymorphic Associations
|
238
|
-
|
239
|
-
TODO
|
240
|
-
|
241
245
|
### Caching Self
|
242
246
|
|
243
247
|
Cache self by id.
|
@@ -324,6 +328,15 @@ This option is needed to know which attribute should be passed to the parameter
|
|
324
328
|
|
325
329
|
- Default value is `:id`
|
326
330
|
|
331
|
+
## Future works
|
332
|
+
|
333
|
+
- [ ] caching polymorphic associations
|
334
|
+
- [ ] non-unique secondary indexes
|
335
|
+
- [ ] caching attibutes by multiple keys
|
336
|
+
- [ ] testing counter cache
|
337
|
+
- [ ] testing has_many through
|
338
|
+
- [ ] testing has_and_belongs_to_many
|
339
|
+
|
327
340
|
## Development
|
328
341
|
|
329
342
|
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.
|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["khiav reoy"]
|
10
10
|
spec.email = ["mrtmrt15xn@yahoo.com.tw"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{
|
12
|
+
spec.summary = %q{Simply cache whatever you want by using cachers. Support Rails 3, 4, 5.}
|
13
|
+
spec.description = %q{Simply cache whatever you want by using cachers which will help you maintain cached objects and expire them when they are changed. Support Rails 3, 4, 5.}
|
14
14
|
spec.homepage = "https://github.com/khiav223577/active_model_cachers"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
data/gemfiles/3.2.gemfile
CHANGED
data/gemfiles/4.2.gemfile
CHANGED
data/gemfiles/5.0.gemfile
CHANGED
data/gemfiles/5.1.gemfile
CHANGED
data/gemfiles/5.2.gemfile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'active_model_cachers/column_value_cache'
|
3
2
|
require 'active_model_cachers/active_record/attr_model'
|
4
3
|
require 'active_model_cachers/active_record/cacher'
|
5
4
|
require 'active_model_cachers/hook/dependencies'
|
@@ -21,13 +20,11 @@ module ActiveModelCachers
|
|
21
20
|
service_klass = CacheServiceFactory.create_for_active_model(attr, query)
|
22
21
|
Cacher.define_cacher_method(attr, attr.primary_key || :id, [service_klass])
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
define_callback_for_cleaning_cache(expire_class, expire_column, foreign_key, on: on) do |id|
|
28
|
-
service_klass.clean_at(with_id ? id : nil)
|
29
|
-
end
|
23
|
+
if (infos = get_expire_infos(attr, expire_by, foreign_key))
|
24
|
+
with_id = (expire_by.is_a?(Symbol) || query.parameters.size == 1)
|
25
|
+
service_klass.define_callback_for_cleaning_cache(*infos, with_id, on: on)
|
30
26
|
end
|
27
|
+
|
31
28
|
return service_klass
|
32
29
|
end
|
33
30
|
|
@@ -72,33 +69,6 @@ module ActiveModelCachers
|
|
72
69
|
service_klasses << cache_self
|
73
70
|
end
|
74
71
|
end
|
75
|
-
|
76
|
-
@@column_value_cache = ActiveModelCachers::ColumnValueCache.new
|
77
|
-
def define_callback_for_cleaning_cache(class_name, column, foreign_key, on: nil, &clean)
|
78
|
-
ActiveSupport::Dependencies.onload(class_name) do
|
79
|
-
clean_ids = []
|
80
|
-
|
81
|
-
prepend_before_delete do |id, model|
|
82
|
-
clean_ids << @@column_value_cache.add(self, class_name, id, foreign_key, model)
|
83
|
-
end
|
84
|
-
|
85
|
-
before_delete do |_, model|
|
86
|
-
clean_ids.each{|s| clean.call(s.call) }
|
87
|
-
clean_ids = []
|
88
|
-
end
|
89
|
-
|
90
|
-
after_delete do
|
91
|
-
@@column_value_cache.clean_cache()
|
92
|
-
end
|
93
|
-
|
94
|
-
on_nullify(column){|ids| ids.each{|s| clean.call(s) }}
|
95
|
-
|
96
|
-
after_commit ->{
|
97
|
-
changed = column ? previous_changes.key?(column) : previous_changes.present?
|
98
|
-
clean.call(send(foreign_key)) if changed || destroyed?
|
99
|
-
}, on: on
|
100
|
-
end
|
101
|
-
end
|
102
72
|
end
|
103
73
|
end
|
104
74
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'active_model_cachers/nil_object'
|
3
3
|
require 'active_model_cachers/false_object'
|
4
|
+
require 'active_model_cachers/column_value_cache'
|
4
5
|
|
5
6
|
module ActiveModelCachers
|
6
7
|
class CacheService
|
@@ -16,6 +17,40 @@ module ActiveModelCachers
|
|
16
17
|
def clean_at(id)
|
17
18
|
instance(id).clean_cache
|
18
19
|
end
|
20
|
+
|
21
|
+
@@column_value_cache = ActiveModelCachers::ColumnValueCache.new
|
22
|
+
def define_callback_for_cleaning_cache(class_name, column, foreign_key, with_id, on: nil)
|
23
|
+
return if @callbacks_defined
|
24
|
+
@callbacks_defined = true
|
25
|
+
|
26
|
+
clean = ->(id){ clean_at(with_id ? id : nil) }
|
27
|
+
|
28
|
+
ActiveSupport::Dependencies.onload(class_name) do
|
29
|
+
clean_ids = []
|
30
|
+
|
31
|
+
prepend_before_delete do |id, model|
|
32
|
+
clean_ids << @@column_value_cache.add(self, class_name, id, foreign_key, model)
|
33
|
+
end
|
34
|
+
|
35
|
+
before_delete do |_, model|
|
36
|
+
clean_ids.each{|s| clean.call(s.call) }
|
37
|
+
clean_ids = []
|
38
|
+
end
|
39
|
+
|
40
|
+
after_delete do
|
41
|
+
@@column_value_cache.clean_cache
|
42
|
+
end
|
43
|
+
|
44
|
+
on_nullify(column){|ids| ids.each{|s| clean.call(s) }}
|
45
|
+
|
46
|
+
after_commit ->{
|
47
|
+
changed = column ? previous_changes.key?(column) : previous_changes.present?
|
48
|
+
clean.call(send(foreign_key)) if changed || destroyed?
|
49
|
+
}, on: on
|
50
|
+
|
51
|
+
after_touch ->{ clean.call(send(foreign_key)) }
|
52
|
+
end
|
53
|
+
end
|
19
54
|
end
|
20
55
|
|
21
56
|
# ----------------------------------------------------------------
|
@@ -22,6 +22,7 @@ module ActiveModelCachers
|
|
22
22
|
klass = Class.new(CacheService)
|
23
23
|
klass.cache_key = cache_key
|
24
24
|
klass.query = query
|
25
|
+
klass.instance_variable_set(:@callbacks_defined, false) # to remove warning: instance variable @callbacks_defined not initialized
|
25
26
|
next klass
|
26
27
|
}[]
|
27
28
|
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
|
+
version: 2.1.1
|
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-05-
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,9 +94,8 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '3'
|
97
|
-
description:
|
98
|
-
|
99
|
-
(by create, update, destroy, and even delete). Support Rails 3, 4, 5.
|
97
|
+
description: Simply cache whatever you want by using cachers which will help you maintain
|
98
|
+
cached objects and expire them when they are changed. Support Rails 3, 4, 5.
|
100
99
|
email:
|
101
100
|
- mrtmrt15xn@yahoo.com.tw
|
102
101
|
executables: []
|
@@ -105,6 +104,7 @@ extra_rdoc_files: []
|
|
105
104
|
files:
|
106
105
|
- ".gitignore"
|
107
106
|
- ".travis.yml"
|
107
|
+
- CHANGELOG.md
|
108
108
|
- CODE_OF_CONDUCT.md
|
109
109
|
- LICENSE.txt
|
110
110
|
- README.md
|
@@ -155,6 +155,5 @@ rubyforge_project:
|
|
155
155
|
rubygems_version: 2.7.6
|
156
156
|
signing_key:
|
157
157
|
specification_version: 4
|
158
|
-
summary:
|
159
|
-
model. Support Rails 3, 4, 5.
|
158
|
+
summary: Simply cache whatever you want by using cachers. Support Rails 3, 4, 5.
|
160
159
|
test_files: []
|