active_model_cachers 2.1.5 → 2.1.6

Sign up to get free protection for your applications and to get access to all the features.
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"
8
+ end
9
+
10
+ gemspec :path => "../"
11
+
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"
8
+ end
9
+
10
+ gemspec :path => "../"
11
+
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"
8
+ end
9
+
10
+ gemspec :path => "../"
11
+
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"
8
+ end
9
+
10
+ gemspec :path => "../"
11
+
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"
8
+ end
9
+
10
+ gemspec :path => "../"
11
+
File without changes
@@ -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
@@ -1,97 +1,97 @@
1
- # frozen_string_literal: true
2
- module ActiveModelCachers
3
- module ActiveRecord
4
- class Cacher
5
- @defined_map = {}
6
-
7
- class << self
8
- def get_cacher_klass(klass)
9
- @defined_map[klass] ||= create_cacher_klass_at(klass)
10
- end
11
-
12
- def define_cacher_method(attr, primary_key, service_klasses)
13
- cacher_klass = get_cacher_klass(attr.klass)
14
- method = attr.column
15
- return cacher_klass.define_find_by(attr, primary_key, service_klasses) if method == nil
16
- cacher_klass.send(:define_methods, method, {
17
- method => ->{ exec_by(attr, primary_key, service_klasses, :get) },
18
- "peek_#{method}" => ->{ exec_by(attr, primary_key, service_klasses, :peek) },
19
- "clean_#{method}" => ->{ exec_by(attr, primary_key, service_klasses, :clean_cache) },
20
- })
21
- end
22
-
23
- def define_find_by(attr, primary_key, service_klasses)
24
- if @find_by_mapping == nil
25
- @find_by_mapping = {}
26
- define_methods(:find_by, {
27
- :find_by => ->(args){ exec_find_by(args, :get) },
28
- :peek_by => ->(args){ exec_find_by(args, :peek) },
29
- :clean_by => ->(args){ exec_find_by(args, :clean_cache) },
30
- })
31
- end
32
- @find_by_mapping[primary_key] = [attr, service_klasses]
33
- end
34
-
35
- private
36
-
37
- def define_methods(attribute, methods_mapping)
38
- if attributes.include?(attribute)
39
- methods_mapping.keys.each{|s| undef_method(s) }
40
- else
41
- attributes << attribute
42
- end
43
- methods_mapping.each{|method, block| define_method(method, &block) }
44
- end
45
-
46
- def get_data_from_find_by_mapping(primary_key)
47
- return if @find_by_mapping == nil
48
- return @find_by_mapping[primary_key]
49
- end
50
-
51
- def create_cacher_klass_at(target)
52
- cacher_klass = Class.new(self)
53
- cacher_klass.instance_variable_set(:@find_by_mapping, nil) # to remove warning: instance variable @find_by_mapping not initialized
54
- cacher_klass.define_singleton_method(:attributes){ @attributes ||= [] }
55
- cacher_klass.send(:define_method, 'peek'){|column| send("peek_#{column}") }
56
- cacher_klass.send(:define_method, 'clean'){|column| send("clean_#{column}") }
57
-
58
- target.define_singleton_method(:cacher_at){|id| cacher_klass.new(id: id) }
59
- target.define_singleton_method(:cacher){ cacher_klass.new }
60
- target.send(:define_method, :cacher){ cacher_klass.new(model: self) }
61
- return cacher_klass
62
- end
63
- end
64
-
65
- def initialize(id: nil, model: nil)
66
- @id = id
67
- @model = model
68
- end
69
-
70
- private
71
-
72
- def exec_find_by(args, method) # e.g. args = {course_id: xx}
73
- primary_key = args.keys.sort.first # Support only one key now.
74
- attr, service_klasses = self.class.send(:get_data_from_find_by_mapping, primary_key)
75
- return if service_klasses == nil
76
- return exec_by(attr, primary_key, service_klasses, method, data: args[primary_key])
77
- end
78
-
79
- def exec_by(attr, primary_key, service_klasses, method, data: nil)
80
- bindings = [@model]
81
- reflects = (attr.belongs_to? ? [] : [attr.reflect])
82
- if @model and attr.association?
83
- if attr.belongs_to? and method != :clean_cache # no need to load binding when just cleaning cache
84
- association = @model.association(attr.column)
85
- bindings << association.load_target if association.loaded?
86
- end
87
- end
88
- data ||= (@model ? @model.send(primary_key) : nil) || @id
89
- service_klasses.each_with_index do |service_klass, index|
90
- data = service_klass.instance(data).send(method, binding: bindings[index], reflect: reflects[index])
91
- return if data == nil
92
- end
93
- return data
94
- end
95
- end
96
- end
97
- end
1
+ # frozen_string_literal: true
2
+ module ActiveModelCachers
3
+ module ActiveRecord
4
+ class Cacher
5
+ @defined_map = {}
6
+
7
+ class << self
8
+ def get_cacher_klass(klass)
9
+ @defined_map[klass] ||= create_cacher_klass_at(klass)
10
+ end
11
+
12
+ def define_cacher_method(attr, primary_key, service_klasses)
13
+ cacher_klass = get_cacher_klass(attr.klass)
14
+ method = attr.column
15
+ return cacher_klass.define_find_by(attr, primary_key, service_klasses) if method == nil
16
+ cacher_klass.send(:define_methods, method, {
17
+ method => ->{ exec_by(attr, primary_key, service_klasses, :get) },
18
+ "peek_#{method}" => ->{ exec_by(attr, primary_key, service_klasses, :peek) },
19
+ "clean_#{method}" => ->{ exec_by(attr, primary_key, service_klasses, :clean_cache) },
20
+ })
21
+ end
22
+
23
+ def define_find_by(attr, primary_key, service_klasses)
24
+ if @find_by_mapping == nil
25
+ @find_by_mapping = {}
26
+ define_methods(:find_by, {
27
+ :find_by => ->(args){ exec_find_by(args, :get) },
28
+ :peek_by => ->(args){ exec_find_by(args, :peek) },
29
+ :clean_by => ->(args){ exec_find_by(args, :clean_cache) },
30
+ })
31
+ end
32
+ @find_by_mapping[primary_key] = [attr, service_klasses]
33
+ end
34
+
35
+ private
36
+
37
+ def define_methods(attribute, methods_mapping)
38
+ if attributes.include?(attribute)
39
+ methods_mapping.keys.each{|s| undef_method(s) }
40
+ else
41
+ attributes << attribute
42
+ end
43
+ methods_mapping.each{|method, block| define_method(method, &block) }
44
+ end
45
+
46
+ def get_data_from_find_by_mapping(primary_key)
47
+ return if @find_by_mapping == nil
48
+ return @find_by_mapping[primary_key]
49
+ end
50
+
51
+ def create_cacher_klass_at(target)
52
+ cacher_klass = Class.new(self)
53
+ cacher_klass.instance_variable_set(:@find_by_mapping, nil) # to remove warning: instance variable @find_by_mapping not initialized
54
+ cacher_klass.define_singleton_method(:attributes){ @attributes ||= [] }
55
+ cacher_klass.send(:define_method, 'peek'){|column| send("peek_#{column}") }
56
+ cacher_klass.send(:define_method, 'clean'){|column| send("clean_#{column}") }
57
+
58
+ target.define_singleton_method(:cacher_at){|id| cacher_klass.new(id: id) }
59
+ target.define_singleton_method(:cacher){ cacher_klass.new }
60
+ target.send(:define_method, :cacher){ cacher_klass.new(model: self) }
61
+ return cacher_klass
62
+ end
63
+ end
64
+
65
+ def initialize(id: nil, model: nil)
66
+ @id = id
67
+ @model = model
68
+ end
69
+
70
+ private
71
+
72
+ def exec_find_by(args, method) # e.g. args = {course_id: xx}
73
+ primary_key = args.keys.sort.first # Support only one key now.
74
+ attr, service_klasses = self.class.send(:get_data_from_find_by_mapping, primary_key)
75
+ return if service_klasses == nil
76
+ return exec_by(attr, primary_key, service_klasses, method, data: args[primary_key])
77
+ end
78
+
79
+ def exec_by(attr, primary_key, service_klasses, method, data: nil)
80
+ bindings = [@model]
81
+ reflects = (attr.belongs_to? ? [] : [attr.reflect])
82
+ if @model and attr.association?
83
+ if attr.belongs_to? and method != :clean_cache # no need to load binding when just cleaning cache
84
+ association = @model.association(attr.column)
85
+ bindings << association.load_target if association.loaded?
86
+ end
87
+ end
88
+ data ||= (@model ? @model.send(primary_key) : nil) || @id
89
+ service_klasses.each_with_index do |service_klass, index|
90
+ data = service_klass.instance(data).send(method, binding: bindings[index], reflect: reflects[index])
91
+ return if data == nil
92
+ end
93
+ return data
94
+ end
95
+ end
96
+ end
97
+ end