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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +59 -0
  3. data/.gitignore +9 -9
  4. data/CHANGELOG.md +71 -50
  5. data/CODE_OF_CONDUCT.md +48 -48
  6. data/LICENSE.txt +21 -21
  7. data/README.md +399 -353
  8. data/Rakefile +10 -10
  9. data/active_model_cachers.gemspec +45 -38
  10. data/bin/console +14 -14
  11. data/bin/setup +8 -8
  12. data/gemfiles/3.2.gemfile +11 -11
  13. data/gemfiles/4.2.gemfile +11 -11
  14. data/gemfiles/5.0.gemfile +11 -11
  15. data/gemfiles/5.1.gemfile +11 -11
  16. data/gemfiles/5.2.gemfile +11 -11
  17. data/gemfiles/6.0.gemfile +11 -0
  18. data/lib/active_model_cachers.rb +11 -0
  19. data/lib/active_model_cachers/active_record/attr_model.rb +124 -103
  20. data/lib/active_model_cachers/active_record/cacher.rb +97 -96
  21. data/lib/active_model_cachers/active_record/extension.rb +119 -106
  22. data/lib/active_model_cachers/active_record/global_callbacks.rb +67 -59
  23. data/lib/active_model_cachers/cache_service.rb +151 -134
  24. data/lib/active_model_cachers/cache_service_factory.rb +55 -55
  25. data/lib/active_model_cachers/column_value_cache.rb +47 -46
  26. data/lib/active_model_cachers/config.rb +6 -6
  27. data/lib/active_model_cachers/false_object.rb +5 -5
  28. data/lib/active_model_cachers/hook/associations.rb +43 -43
  29. data/lib/active_model_cachers/hook/dependencies.rb +38 -38
  30. data/lib/active_model_cachers/hook/on_model_delete.rb +29 -29
  31. data/lib/active_model_cachers/nil_object.rb +5 -5
  32. data/lib/active_model_cachers/{active_record → patches}/patch_rails_3.rb +49 -49
  33. data/lib/active_model_cachers/patches/uninitialized_attribute.rb +9 -0
  34. data/lib/active_model_cachers/version.rb +4 -4
  35. metadata +31 -13
  36. 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
- spec.add_development_dependency "bundler", "~> 1.11"
31
- spec.add_development_dependency "rake", "~> 12.0"
32
- spec.add_development_dependency "sqlite3", "~> 1.3"
33
- spec.add_development_dependency "minitest", "~> 5.0"
34
-
35
- spec.add_dependency "request_store", "~> 1.4.0"
36
- spec.add_dependency "activerecord", ">= 3"
37
-
38
- end
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 "activerecord", "~> 3.2.0"
4
- gem "request_store", "~> 1.4.0"
5
-
6
- group :test do
7
- gem "simplecov"
8
- end
9
-
10
- gemspec :path => "../"
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 "activerecord", "~> 4.2.0"
4
- gem "request_store", "~> 1.4.0"
5
-
6
- group :test do
7
- gem "simplecov"
8
- end
9
-
10
- gemspec :path => "../"
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 "activerecord", "~> 5.0.0"
4
- gem "request_store", "~> 1.4.0"
5
-
6
- group :test do
7
- gem "simplecov"
8
- end
9
-
10
- gemspec :path => "../"
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 "activerecord", "~> 5.1.0"
4
- gem "request_store", "~> 1.4.0"
5
-
6
- group :test do
7
- gem "simplecov"
8
- end
9
-
10
- gemspec :path => "../"
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 "activerecord", "~> 5.2.0"
4
- gem "request_store", "~> 1.4.0"
5
-
6
- group :test do
7
- gem "simplecov"
8
- end
9
-
10
- gemspec :path => "../"
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: '../'
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 6.0.0'
4
+ gem 'request_store', '~> 1.4.1'
5
+
6
+ group :test do
7
+ gem 'simplecov', '< 0.18'
8
+ gem 'sqlite3', '~> 1.4.1'
9
+ end
10
+
11
+ gemspec path: '../'
@@ -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 belongs_to?
33
- return false if not association?
34
- return @reflect.belongs_to?
35
- end
36
-
37
- def has_one?
38
- return false if not association?
39
- #return @reflect.has_one? # Rails 3 doesn't have this method
40
- return false if @reflect.collection?
41
- return false if @reflect.belongs_to?
42
- return true
43
- end
44
-
45
- def primary_key
46
- return @primary_key if @primary_key
47
- return if not association?
48
- return (@reflect.belongs_to? ? @reflect.klass : @reflect.active_record).primary_key
49
- end
50
-
51
- def foreign_key(reverse: false)
52
- return @foreign_key if @foreign_key
53
- return if not association?
54
- # key may be symbol if specify foreign_key in association options
55
- return @reflect.chain.last.foreign_key.to_s if reverse and join_table
56
- return (@reflect.belongs_to? == reverse ? primary_key : @reflect.foreign_key).to_s
57
- end
58
-
59
- def single_association?
60
- return false if not association?
61
- return !collection?
62
- end
63
-
64
- def collection?
65
- return false if not association?
66
- return @reflect.collection?
67
- end
68
-
69
- def query_model(binding, id)
70
- return query_self(binding, id) if @column == nil
71
- return query_association(binding, id) if association?
72
- return query_attribute(binding, id)
73
- end
74
-
75
- def extract_class_and_column
76
- return [class_name, nil] if single_association?
77
- return [@klass.to_s, @column]
78
- end
79
-
80
- private
81
-
82
- def query_self(binding, id)
83
- return binding if binding.is_a?(::ActiveRecord::Base)
84
- return @klass.find_by(primary_key => id)
85
- end
86
-
87
- def query_attribute(binding, id)
88
- return binding.send(@column) if binding.is_a?(::ActiveRecord::Base) and binding.has_attribute?(@column)
89
- return @klass.where(id: id).limit(1).pluck(@column).first
90
- end
91
-
92
- def query_association(binding, id)
93
- return binding.association(@column).load_target if binding.is_a?(::ActiveRecord::Base)
94
- id = @reflect.active_record.where(id: id).limit(1).pluck(foreign_key).first if foreign_key != 'id'
95
- case
96
- when collection? ; return id ? @reflect.klass.where(@reflect.foreign_key => id).to_a : []
97
- when has_one? ; return id ? @reflect.klass.find_by(foreign_key(reverse: true) => id) : nil
98
- else ; return id ? @reflect.klass.find_by(primary_key => id) : nil
99
- end
100
- end
101
- end
102
- end
103
- end
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