active_model_cachers 2.1.6 → 2.1.7

Sign up to get free protection for your applications and to get access to all the features.
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)