active_model_cachers 2.1.3 → 2.1.8
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/.github/workflows/ruby.yml +59 -0
- data/.gitignore +9 -9
- data/CHANGELOG.md +71 -50
- data/CODE_OF_CONDUCT.md +48 -48
- data/LICENSE.txt +21 -21
- data/README.md +399 -353
- data/Rakefile +10 -10
- data/active_model_cachers.gemspec +45 -38
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/gemfiles/3.2.gemfile +11 -11
- data/gemfiles/4.2.gemfile +11 -11
- data/gemfiles/5.0.gemfile +11 -11
- data/gemfiles/5.1.gemfile +11 -11
- data/gemfiles/5.2.gemfile +11 -11
- data/gemfiles/6.0.gemfile +11 -0
- data/lib/active_model_cachers.rb +11 -0
- data/lib/active_model_cachers/active_record/attr_model.rb +124 -103
- data/lib/active_model_cachers/active_record/cacher.rb +97 -96
- data/lib/active_model_cachers/active_record/extension.rb +119 -106
- data/lib/active_model_cachers/active_record/global_callbacks.rb +67 -59
- data/lib/active_model_cachers/cache_service.rb +151 -134
- data/lib/active_model_cachers/cache_service_factory.rb +55 -55
- data/lib/active_model_cachers/column_value_cache.rb +47 -46
- data/lib/active_model_cachers/config.rb +6 -6
- data/lib/active_model_cachers/false_object.rb +5 -5
- data/lib/active_model_cachers/hook/associations.rb +43 -43
- data/lib/active_model_cachers/hook/dependencies.rb +38 -38
- data/lib/active_model_cachers/hook/on_model_delete.rb +29 -29
- data/lib/active_model_cachers/nil_object.rb +5 -5
- data/lib/active_model_cachers/{active_record → patches}/patch_rails_3.rb +49 -49
- data/lib/active_model_cachers/patches/uninitialized_attribute.rb +9 -0
- data/lib/active_model_cachers/version.rb +4 -4
- metadata +31 -13
- data/.travis.yml +0 -26
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rake/testtask"
|
3
|
-
|
4
|
-
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs << "test"
|
6
|
-
t.libs << "lib"
|
7
|
-
t.test_files = FileList['test/**/*_test.rb']
|
8
|
-
end
|
9
|
-
|
10
|
-
task :default => :test
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :test
|
@@ -1,38 +1,45 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'active_model_cachers/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "active_model_cachers"
|
8
|
-
spec.version = ActiveModelCachers::VERSION
|
9
|
-
spec.authors = ["khiav reoy"]
|
10
|
-
spec.email = ["mrtmrt15xn@yahoo.com.tw"]
|
11
|
-
|
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
|
-
spec.homepage = "https://github.com/khiav223577/active_model_cachers"
|
15
|
-
spec.license = "MIT"
|
16
|
-
|
17
|
-
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
-
# delete this section to allow pushing this gem to any host.
|
19
|
-
#if spec.respond_to?(:metadata)
|
20
|
-
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
-
#else
|
22
|
-
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
-
#end
|
24
|
-
|
25
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
-
spec.bindir = "exe"
|
27
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = ["lib"]
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_model_cachers/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "active_model_cachers"
|
8
|
+
spec.version = ActiveModelCachers::VERSION
|
9
|
+
spec.authors = ["khiav reoy"]
|
10
|
+
spec.email = ["mrtmrt15xn@yahoo.com.tw"]
|
11
|
+
|
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
|
+
spec.homepage = "https://github.com/khiav223577/active_model_cachers"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
#if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
#else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
#end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
spec.metadata = {
|
30
|
+
'homepage_uri' => 'https://github.com/khiav223577/active_model_cachers',
|
31
|
+
'changelog_uri' => 'https://github.com/khiav223577/active_model_cachers/blob/master/CHANGELOG.md',
|
32
|
+
'source_code_uri' => 'https://github.com/khiav223577/active_model_cachers',
|
33
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/active_model_cachers',
|
34
|
+
'bug_tracker_uri' => 'https://github.com/khiav223577/active_model_cachers/issues',
|
35
|
+
}
|
36
|
+
|
37
|
+
spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x'
|
38
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
39
|
+
spec.add_development_dependency "sqlite3", "~> 1.3"
|
40
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
41
|
+
|
42
|
+
spec.add_dependency 'request_store', '>= 1.4.0', '< 1.6.0'
|
43
|
+
spec.add_dependency "activerecord", ">= 3"
|
44
|
+
|
45
|
+
end
|
data/bin/console
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "active_model_cachers"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "active_model_cachers"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
set -vx
|
5
|
-
|
6
|
-
bundle install --gemfile=gemfiles/3.2.gemfile
|
7
|
-
|
8
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
set -vx
|
5
|
+
|
6
|
+
bundle install --gemfile=gemfiles/3.2.gemfile
|
7
|
+
|
8
|
+
# Do any other automated setup that you need to do here
|
data/gemfiles/3.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 3.2.0'
|
4
|
+
gem 'request_store', '~> 1.4.0'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov', '< 0.18'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/4.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 4.2.0'
|
4
|
+
gem 'request_store', '~> 1.4.0'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov', '< 0.18'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.0.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.0.0'
|
4
|
+
gem 'request_store', '~> 1.4.0'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov', '< 0.18'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.1.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.1.0'
|
4
|
+
gem 'request_store', '~> 1.4.0'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov', '< 0.18'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.2.0'
|
4
|
+
gem 'request_store', '~> 1.4.0'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov', '< 0.18'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
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
|
+
|
@@ -1,103 +1,124 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module ActiveModelCachers
|
3
|
-
module ActiveRecord
|
4
|
-
class AttrModel
|
5
|
-
attr_reader :klass, :column, :reflect
|
6
|
-
|
7
|
-
def initialize(klass, column, primary_key: nil, foreign_key: nil)
|
8
|
-
@klass = klass
|
9
|
-
@column = column
|
10
|
-
@primary_key = primary_key
|
11
|
-
@foreign_key = foreign_key
|
12
|
-
@reflect = klass.reflect_on_association(column)
|
13
|
-
end
|
14
|
-
|
15
|
-
def association?
|
16
|
-
return (@reflect != nil)
|
17
|
-
end
|
18
|
-
|
19
|
-
def class_name
|
20
|
-
return if not association?
|
21
|
-
return @reflect.class_name
|
22
|
-
end
|
23
|
-
|
24
|
-
def join_table
|
25
|
-
return nil if @reflect == nil
|
26
|
-
options = @reflect.options
|
27
|
-
return options[:through] if options[:through]
|
28
|
-
return (options[:join_table] || @reflect.send(:derive_join_table)) if @reflect.macro == :has_and_belongs_to_many
|
29
|
-
return nil
|
30
|
-
end
|
31
|
-
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
return @
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
return
|
53
|
-
return if
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
return
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
return
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
return
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
return binding if
|
84
|
-
return
|
85
|
-
end
|
86
|
-
|
87
|
-
def
|
88
|
-
return
|
89
|
-
return @klass.
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ActiveModelCachers
|
3
|
+
module ActiveRecord
|
4
|
+
class AttrModel
|
5
|
+
attr_reader :klass, :column, :reflect
|
6
|
+
|
7
|
+
def initialize(klass, column, primary_key: nil, foreign_key: nil)
|
8
|
+
@klass = klass
|
9
|
+
@column = column
|
10
|
+
@primary_key = primary_key
|
11
|
+
@foreign_key = foreign_key
|
12
|
+
@reflect = klass.reflect_on_association(column)
|
13
|
+
end
|
14
|
+
|
15
|
+
def association?
|
16
|
+
return (@reflect != nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
def class_name
|
20
|
+
return if not association?
|
21
|
+
return @reflect.class_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def join_table
|
25
|
+
return nil if @reflect == nil
|
26
|
+
options = @reflect.options
|
27
|
+
return options[:through] if options[:through]
|
28
|
+
return (options[:join_table] || @reflect.send(:derive_join_table)) if @reflect.macro == :has_and_belongs_to_many
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def join_table_class_name
|
33
|
+
join_table.try{|table_name| @klass.reflect_on_association(table_name).try(:class_name) || through_klass.name }
|
34
|
+
end
|
35
|
+
|
36
|
+
def through_reflection
|
37
|
+
@klass.new.association(@column).reflection.through_reflection
|
38
|
+
end
|
39
|
+
|
40
|
+
def through_klass
|
41
|
+
through_reflection.try(:klass) || through_klass_for_rails_3
|
42
|
+
end
|
43
|
+
|
44
|
+
def belongs_to?
|
45
|
+
return false if not association?
|
46
|
+
return @reflect.belongs_to?
|
47
|
+
end
|
48
|
+
|
49
|
+
def has_one?
|
50
|
+
return false if not association?
|
51
|
+
#return @reflect.has_one? # Rails 3 doesn't have this method
|
52
|
+
return false if @reflect.collection?
|
53
|
+
return false if @reflect.belongs_to?
|
54
|
+
return true
|
55
|
+
end
|
56
|
+
|
57
|
+
def primary_key
|
58
|
+
return @primary_key if @primary_key
|
59
|
+
return if not association?
|
60
|
+
return (@reflect.belongs_to? ? @reflect.klass : @reflect.active_record).primary_key
|
61
|
+
end
|
62
|
+
|
63
|
+
def foreign_key(reverse: false)
|
64
|
+
return @foreign_key if @foreign_key
|
65
|
+
return if not association?
|
66
|
+
# key may be symbol if specify foreign_key in association options
|
67
|
+
return @reflect.chain.last.foreign_key.to_s if reverse and join_table
|
68
|
+
return (@reflect.belongs_to? == reverse ? primary_key : @reflect.foreign_key).to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
def single_association?
|
72
|
+
return false if not association?
|
73
|
+
return !collection?
|
74
|
+
end
|
75
|
+
|
76
|
+
def collection?
|
77
|
+
return false if not association?
|
78
|
+
return @reflect.collection?
|
79
|
+
end
|
80
|
+
|
81
|
+
def query_model(binding, id)
|
82
|
+
return query_self(binding, id) if @column == nil
|
83
|
+
return query_association(binding, id) if association?
|
84
|
+
return query_attribute(binding, id)
|
85
|
+
end
|
86
|
+
|
87
|
+
def extract_class_and_column
|
88
|
+
return [class_name, nil] if single_association?
|
89
|
+
return [@klass.to_s, @column]
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def query_self(binding, id)
|
95
|
+
return binding if binding.is_a?(::ActiveRecord::Base)
|
96
|
+
return @klass.find_by(primary_key => id)
|
97
|
+
end
|
98
|
+
|
99
|
+
def query_attribute(binding, id)
|
100
|
+
return binding.send(@column) if binding.is_a?(::ActiveRecord::Base) and binding.has_attribute?(@column)
|
101
|
+
return @klass.where(id: id).limit(1).pluck(@column).first
|
102
|
+
end
|
103
|
+
|
104
|
+
def query_association(binding, id)
|
105
|
+
return binding.association(@column).load_target if binding.is_a?(::ActiveRecord::Base)
|
106
|
+
id = @reflect.active_record.where(id: id).limit(1).pluck(foreign_key).first if foreign_key != 'id'
|
107
|
+
case
|
108
|
+
when collection? ; return id ? @reflect.klass.where(@reflect.foreign_key => id).to_a : []
|
109
|
+
when has_one? ; return id ? @reflect.klass.find_by(foreign_key(reverse: true) => id) : nil
|
110
|
+
else ; return id ? @reflect.klass.find_by(primary_key => id) : nil
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def through_klass_for_rails_3
|
115
|
+
const_name = "HABTM_#{@reflect.klass.name.pluralize}"
|
116
|
+
@klass.const_defined?(const_name) ? @klass.const_get(const_name) : @klass.const_set(const_name, create_through_klass_for_rails_3)
|
117
|
+
end
|
118
|
+
|
119
|
+
def create_through_klass_for_rails_3
|
120
|
+
Class.new(::ActiveRecord::Base).tap{|s| s.table_name = join_table }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|