active_model_cachers 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![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 (
|
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: []
|