active_model_cachers 2.1.6 → 2.1.7

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 (35) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +9 -9
  3. data/.travis.yml +8 -1
  4. data/CHANGELOG.md +67 -62
  5. data/CODE_OF_CONDUCT.md +48 -48
  6. data/LICENSE.txt +21 -21
  7. data/README.md +1 -1
  8. data/Rakefile +10 -10
  9. data/active_model_cachers.gemspec +7 -0
  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 +0 -0
  19. data/lib/active_model_cachers/active_record/attr_model.rb +124 -124
  20. data/lib/active_model_cachers/active_record/cacher.rb +97 -97
  21. data/lib/active_model_cachers/active_record/extension.rb +119 -119
  22. data/lib/active_model_cachers/active_record/global_callbacks.rb +67 -67
  23. data/lib/active_model_cachers/cache_service.rb +151 -151
  24. data/lib/active_model_cachers/cache_service_factory.rb +55 -55
  25. data/lib/active_model_cachers/column_value_cache.rb +47 -47
  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/patches/patch_rails_3.rb +49 -49
  33. data/lib/active_model_cachers/patches/uninitialized_attribute.rb +9 -9
  34. data/lib/active_model_cachers/version.rb +4 -4
  35. metadata +10 -4
@@ -1,55 +1,55 @@
1
- # frozen_string_literal: true
2
- require 'request_store'
3
- require 'active_model_cachers/cache_service'
4
-
5
- module ActiveModelCachers
6
- class CacheServiceFactory
7
- @key_class_mapping = {}
8
- @cache_key_klass_mapping = {}
9
-
10
- class << self
11
- def has_cacher?(attr)
12
- return (@key_class_mapping[get_cache_key(attr)] != nil)
13
- end
14
-
15
- def create_for_active_model(attr, query)
16
- cache_key = get_cache_key(attr)
17
-
18
- klass = @key_class_mapping[cache_key] ||= ->{
19
- klass = Class.new(CacheService)
20
- klass.cache_key = cache_key
21
- klass.query_mapping = {}
22
- klass.instance_variable_set(:@callbacks_defined, false) # to remove warning: instance variable @callbacks_defined not initialized
23
- next klass
24
- }[]
25
-
26
- klass.query_mapping[attr.reflect] = query
27
- return klass
28
- end
29
-
30
- def set_klass_to_mapping(attr, current_klass)
31
- cache_key = get_cache_key(attr)
32
- changed = clean_klass_cache_if_reloaded!(cache_key, current_klass, attr)
33
- @cache_key_klass_mapping[cache_key] = current_klass
34
- return changed
35
- end
36
-
37
- private
38
-
39
- def get_cache_key(attr)
40
- class_name, column = attr.extract_class_and_column
41
- return "active_model_cachers_#{class_name}_at_#{column}" if column
42
- foreign_key = attr.foreign_key(reverse: true)
43
- return "active_model_cachers_#{class_name}_by_#{foreign_key}" if foreign_key and foreign_key.to_s != 'id'
44
- return "active_model_cachers_#{class_name}"
45
- end
46
-
47
- def clean_klass_cache_if_reloaded!(cache_key, current_klass, attr)
48
- origin_klass, @cache_key_klass_mapping[cache_key] = @cache_key_klass_mapping[cache_key], current_klass
49
- return false if origin_klass == nil or origin_klass == current_klass # when code reloaded in development.
50
- @key_class_mapping[cache_key] = nil
51
- return true
52
- end
53
- end
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+ require 'request_store'
3
+ require 'active_model_cachers/cache_service'
4
+
5
+ module ActiveModelCachers
6
+ class CacheServiceFactory
7
+ @key_class_mapping = {}
8
+ @cache_key_klass_mapping = {}
9
+
10
+ class << self
11
+ def has_cacher?(attr)
12
+ return (@key_class_mapping[get_cache_key(attr)] != nil)
13
+ end
14
+
15
+ def create_for_active_model(attr, query)
16
+ cache_key = get_cache_key(attr)
17
+
18
+ klass = @key_class_mapping[cache_key] ||= ->{
19
+ klass = Class.new(CacheService)
20
+ klass.cache_key = cache_key
21
+ klass.query_mapping = {}
22
+ klass.instance_variable_set(:@callbacks_defined, false) # to remove warning: instance variable @callbacks_defined not initialized
23
+ next klass
24
+ }[]
25
+
26
+ klass.query_mapping[attr.reflect] = query
27
+ return klass
28
+ end
29
+
30
+ def set_klass_to_mapping(attr, current_klass)
31
+ cache_key = get_cache_key(attr)
32
+ changed = clean_klass_cache_if_reloaded!(cache_key, current_klass, attr)
33
+ @cache_key_klass_mapping[cache_key] = current_klass
34
+ return changed
35
+ end
36
+
37
+ private
38
+
39
+ def get_cache_key(attr)
40
+ class_name, column = attr.extract_class_and_column
41
+ return "active_model_cachers_#{class_name}_at_#{column}" if column
42
+ foreign_key = attr.foreign_key(reverse: true)
43
+ return "active_model_cachers_#{class_name}_by_#{foreign_key}" if foreign_key and foreign_key.to_s != 'id'
44
+ return "active_model_cachers_#{class_name}"
45
+ end
46
+
47
+ def clean_klass_cache_if_reloaded!(cache_key, current_klass, attr)
48
+ origin_klass, @cache_key_klass_mapping[cache_key] = @cache_key_klass_mapping[cache_key], current_klass
49
+ return false if origin_klass == nil or origin_klass == current_klass # when code reloaded in development.
50
+ @key_class_mapping[cache_key] = nil
51
+ return true
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,47 +1,47 @@
1
- # frozen_string_literal: true
2
-
3
- class ActiveModelCachers::ColumnValueCache
4
- def initialize
5
- @cache1 = Hash.new{|h, k| h[k] = {} }
6
- @cache2 = Hash.new{|h, k| h[k] = {} }
7
- end
8
-
9
- def add(object, class_name, id, foreign_key, model)
10
- value = (@cache1[class_name][[id, foreign_key]] ||= get_id_from(object, id, foreign_key, model))
11
- return ->{ (value == :not_set ? query_value(object, class_name, id, foreign_key) : value)}
12
- end
13
-
14
- def query_value(object, class_name, id, foreign_key)
15
- cache = @cache2[class_name]
16
- if cache.empty?
17
- no_data_keys = @cache1[class_name].select{|k, v| v == :not_set }.keys
18
- ids = no_data_keys.map(&:first).uniq
19
- columns = ['id', *no_data_keys.map(&:second)].uniq
20
- pluck_columns(object, object.where(id: ids).limit(ids.size), columns).each do |columns_data|
21
- model_id = columns_data.first
22
- columns.each_with_index do |column, index|
23
- cache[[model_id, column]] = columns_data[index]
24
- end
25
- end
26
- end
27
- return cache[[id, foreign_key]]
28
- end
29
-
30
- def clean_cache
31
- @cache1.clear
32
- @cache2.clear
33
- end
34
-
35
- private
36
-
37
- def pluck_columns(_, relation, columns)
38
- relation.pluck(*columns)
39
- end
40
-
41
- def get_id_from(object, id, column, model)
42
- return id if column == 'id'
43
- model ||= object.cacher.peek_by(id: id) if object.has_cacher?
44
- return model.send(column) if model and model.has_attribute?(column)
45
- return :not_set
46
- end
47
- end
1
+ # frozen_string_literal: true
2
+
3
+ class ActiveModelCachers::ColumnValueCache
4
+ def initialize
5
+ @cache1 = Hash.new{|h, k| h[k] = {} }
6
+ @cache2 = Hash.new{|h, k| h[k] = {} }
7
+ end
8
+
9
+ def add(object, class_name, id, foreign_key, model)
10
+ value = (@cache1[class_name][[id, foreign_key]] ||= get_id_from(object, id, foreign_key, model))
11
+ return ->{ (value == :not_set ? query_value(object, class_name, id, foreign_key) : value)}
12
+ end
13
+
14
+ def query_value(object, class_name, id, foreign_key)
15
+ cache = @cache2[class_name]
16
+ if cache.empty?
17
+ no_data_keys = @cache1[class_name].select{|k, v| v == :not_set }.keys
18
+ ids = no_data_keys.map(&:first).uniq
19
+ columns = ['id', *no_data_keys.map(&:second)].uniq
20
+ pluck_columns(object, object.where(id: ids).limit(ids.size), columns).each do |columns_data|
21
+ model_id = columns_data.first
22
+ columns.each_with_index do |column, index|
23
+ cache[[model_id, column]] = columns_data[index]
24
+ end
25
+ end
26
+ end
27
+ return cache[[id, foreign_key]]
28
+ end
29
+
30
+ def clean_cache
31
+ @cache1.clear
32
+ @cache2.clear
33
+ end
34
+
35
+ private
36
+
37
+ def pluck_columns(_, relation, columns)
38
+ relation.pluck(*columns)
39
+ end
40
+
41
+ def get_id_from(object, id, column, model)
42
+ return id if column == 'id'
43
+ model ||= object.cacher.peek_by(id: id) if object.has_cacher?
44
+ return model.send(column) if model and model.has_attribute?(column)
45
+ return :not_set
46
+ end
47
+ end
@@ -1,6 +1,6 @@
1
- # frozen_string_literal: true
2
- module ActiveModelCachers
3
- class Config
4
- attr_accessor :store
5
- end
6
- end
1
+ # frozen_string_literal: true
2
+ module ActiveModelCachers
3
+ class Config
4
+ attr_accessor :store
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
- module ActiveModelCachers
3
- class FalseObject
4
- end
5
- end
1
+ # frozen_string_literal: true
2
+ module ActiveModelCachers
3
+ class FalseObject
4
+ end
5
+ end
@@ -1,43 +1,43 @@
1
- # frozen_string_literal: true
2
- require 'active_record'
3
- require 'active_record/associations/has_many_association'
4
- require 'active_model_cachers/hook/on_model_delete'
5
-
6
- module ActiveModelCachers::Hook
7
- module Associations
8
- def delete_count(method, scope)
9
- if method == :delete_all
10
- # TODO:
11
- else # nullify
12
- call_hooks{ scope.pluck(:id) }
13
- end
14
- super
15
- end
16
-
17
- def delete_records(records, method)
18
- case method
19
- when :destroy
20
- when :delete_all
21
- # TODO:
22
- else
23
- call_hooks{ records.map(&:id) }
24
- end
25
- super
26
- end
27
-
28
- private
29
-
30
- def call_hooks(&get_ids)
31
- ids = nil
32
- get_ids_with_cache = ->{ ids ||= get_ids.call }
33
- ActiveModelCachers::ActiveRecord::Extension.global_callbacks.on_nullify.exec(
34
- self,
35
- reflection.klass,
36
- reflection.foreign_key,
37
- get_ids_with_cache,
38
- )
39
- end
40
- end
41
- end
42
-
43
- ActiveRecord::Associations::HasManyAssociation.send(:prepend, ActiveModelCachers::Hook::Associations)
1
+ # frozen_string_literal: true
2
+ require 'active_record'
3
+ require 'active_record/associations/has_many_association'
4
+ require 'active_model_cachers/hook/on_model_delete'
5
+
6
+ module ActiveModelCachers::Hook
7
+ module Associations
8
+ def delete_count(method, scope)
9
+ if method == :delete_all
10
+ # TODO:
11
+ else # nullify
12
+ call_hooks{ scope.pluck(:id) }
13
+ end
14
+ super
15
+ end
16
+
17
+ def delete_records(records, method)
18
+ case method
19
+ when :destroy
20
+ when :delete_all
21
+ # TODO:
22
+ else
23
+ call_hooks{ records.map(&:id) }
24
+ end
25
+ super
26
+ end
27
+
28
+ private
29
+
30
+ def call_hooks(&get_ids)
31
+ ids = nil
32
+ get_ids_with_cache = ->{ ids ||= get_ids.call }
33
+ ActiveModelCachers::ActiveRecord::Extension.global_callbacks.on_nullify.exec(
34
+ self,
35
+ reflection.klass,
36
+ reflection.foreign_key,
37
+ get_ids_with_cache,
38
+ )
39
+ end
40
+ end
41
+ end
42
+
43
+ ActiveRecord::Associations::HasManyAssociation.send(:prepend, ActiveModelCachers::Hook::Associations)
@@ -1,38 +1,38 @@
1
- # frozen_string_literal: true
2
- require 'active_support/dependencies'
3
-
4
- module ActiveModelCachers::Hook
5
- module Depdenencies
6
- def onload(const_name, times: 1, &block)
7
- const = const_name if not const_name.is_a?(String)
8
- if const or Module.const_defined?(const_name)
9
- (const || const_name.constantize).instance_exec(&block)
10
- else
11
- load_hooks[const_name].push(block: block, times: times)
12
- end
13
- end
14
-
15
- def load_hooks
16
- @load_hooks ||= Hash.new{|h, k| h[k] = [] }
17
- end
18
-
19
- def new_constants_in(*)
20
- new_constants = super.each do |const_name|
21
- hooks = load_hooks[const_name]
22
- need_compact = false
23
- hooks.each_with_index do |hook, idx|
24
- if (hook[:times] -= 1) < 0
25
- hooks[idx] = nil
26
- need_compact = true
27
- next
28
- end
29
- const_name.constantize.instance_exec(&hook[:block])
30
- end
31
- hooks.compact! if need_compact
32
- end
33
- return new_constants
34
- end
35
- end
36
- end
37
-
38
- ActiveSupport::Dependencies.send(:extend, ActiveModelCachers::Hook::Depdenencies)
1
+ # frozen_string_literal: true
2
+ require 'active_support/dependencies'
3
+
4
+ module ActiveModelCachers::Hook
5
+ module Depdenencies
6
+ def onload(const_name, times: 1, &block)
7
+ const = const_name if not const_name.is_a?(String)
8
+ if const or Module.const_defined?(const_name)
9
+ (const || const_name.constantize).instance_exec(&block)
10
+ else
11
+ load_hooks[const_name].push(block: block, times: times)
12
+ end
13
+ end
14
+
15
+ def load_hooks
16
+ @load_hooks ||= Hash.new{|h, k| h[k] = [] }
17
+ end
18
+
19
+ def new_constants_in(*)
20
+ new_constants = super.each do |const_name|
21
+ hooks = load_hooks[const_name]
22
+ need_compact = false
23
+ hooks.each_with_index do |hook, idx|
24
+ if (hook[:times] -= 1) < 0
25
+ hooks[idx] = nil
26
+ need_compact = true
27
+ next
28
+ end
29
+ const_name.constantize.instance_exec(&hook[:block])
30
+ end
31
+ hooks.compact! if need_compact
32
+ end
33
+ return new_constants
34
+ end
35
+ end
36
+ end
37
+
38
+ ActiveSupport::Dependencies.send(:extend, ActiveModelCachers::Hook::Depdenencies)
@@ -1,29 +1,29 @@
1
- # frozen_string_literal: true
2
- require 'active_record'
3
-
4
- module ActiveModelCachers::Hook
5
- module OnModelDelete
6
- module InstanceMethods
7
- def delete
8
- self.class.delete(id, self) if persisted?
9
- @destroyed = true
10
- freeze
11
- end
12
- end
13
-
14
- module ClassMethods
15
- def delete(id, model = nil)
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
-
19
- result = super(id)
20
-
21
- ActiveModelCachers::ActiveRecord::Extension.global_callbacks.after_delete.exec(self, self, id, model)
22
- return result
23
- end
24
- end
25
- end
26
- end
27
-
28
- ActiveRecord::Base.send(:include, ActiveModelCachers::Hook::OnModelDelete::InstanceMethods)
29
- ActiveRecord::Base.send(:extend, ActiveModelCachers::Hook::OnModelDelete::ClassMethods)
1
+ # frozen_string_literal: true
2
+ require 'active_record'
3
+
4
+ module ActiveModelCachers::Hook
5
+ module OnModelDelete
6
+ module InstanceMethods
7
+ def delete
8
+ self.class.delete(id, self) if persisted?
9
+ @destroyed = true
10
+ freeze
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def delete(id, model = nil)
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
+
19
+ result = super(id)
20
+
21
+ ActiveModelCachers::ActiveRecord::Extension.global_callbacks.after_delete.exec(self, self, id, model)
22
+ return result
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ ActiveRecord::Base.send(:include, ActiveModelCachers::Hook::OnModelDelete::InstanceMethods)
29
+ ActiveRecord::Base.send(:extend, ActiveModelCachers::Hook::OnModelDelete::ClassMethods)