active_model_cachers 2.1.7 → 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 +5 -5
- data/.github/workflows/ruby.yml +59 -0
- data/.gitignore +9 -9
- data/CHANGELOG.md +71 -67
- data/CODE_OF_CONDUCT.md +48 -48
- data/LICENSE.txt +21 -21
- data/README.md +399 -390
- data/Rakefile +10 -10
- data/active_model_cachers.gemspec +45 -45
- 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 -11
- data/lib/active_model_cachers/active_record/attr_model.rb +124 -124
- data/lib/active_model_cachers/active_record/cacher.rb +97 -97
- data/lib/active_model_cachers/active_record/extension.rb +119 -119
- data/lib/active_model_cachers/active_record/global_callbacks.rb +67 -67
- data/lib/active_model_cachers/cache_service.rb +151 -151
- data/lib/active_model_cachers/cache_service_factory.rb +55 -55
- data/lib/active_model_cachers/column_value_cache.rb +47 -47
- 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/patches/patch_rails_3.rb +49 -49
- data/lib/active_model_cachers/patches/uninitialized_attribute.rb +9 -9
- data/lib/active_model_cachers/version.rb +4 -4
- metadata +12 -7
- data/.travis.yml +0 -33
@@ -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
|
@@ -1,119 +1,119 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'active_model_cachers/active_record/global_callbacks'
|
3
|
-
require 'active_model_cachers/active_record/attr_model'
|
4
|
-
require 'active_model_cachers/active_record/cacher'
|
5
|
-
require 'active_model_cachers/hook/dependencies'
|
6
|
-
require 'active_model_cachers/hook/associations'
|
7
|
-
require 'active_model_cachers/hook/on_model_delete'
|
8
|
-
|
9
|
-
module ActiveModelCachers
|
10
|
-
module ActiveRecord
|
11
|
-
module Extension
|
12
|
-
def cache_self(by: :id)
|
13
|
-
cache_at(nil, expire_by: self.name, primary_key: by, foreign_key: by)
|
14
|
-
end
|
15
|
-
|
16
|
-
def cache_at(column, query = nil, expire_by: nil, on: nil, foreign_key: nil, primary_key: nil)
|
17
|
-
attr = AttrModel.new(self, column, foreign_key: foreign_key, primary_key: primary_key)
|
18
|
-
return cache_belongs_to(attr) if attr.belongs_to?
|
19
|
-
|
20
|
-
loaded = false
|
21
|
-
class_name, *infos = get_expire_infos(attr, expire_by, foreign_key)
|
22
|
-
set_klass_to_mapping(attr, class_name) do
|
23
|
-
next if !loaded
|
24
|
-
cache_at(column, query, expire_by: expire_by, on: on, foreign_key: foreign_key, primary_key: primary_key)
|
25
|
-
end
|
26
|
-
loaded = true
|
27
|
-
|
28
|
-
query ||= ->(id){ attr.query_model(self, id) }
|
29
|
-
service_klass = CacheServiceFactory.create_for_active_model(attr, query)
|
30
|
-
Cacher.define_cacher_method(attr, attr.primary_key || :id, [service_klass])
|
31
|
-
|
32
|
-
if class_name
|
33
|
-
with_id = (expire_by.is_a?(Symbol) || query.parameters.size == 1)
|
34
|
-
service_klass.define_callback_for_cleaning_cache(class_name, *infos, with_id, on: on)
|
35
|
-
end
|
36
|
-
|
37
|
-
return service_klass
|
38
|
-
end
|
39
|
-
|
40
|
-
def has_cacher?(column = nil)
|
41
|
-
attr = AttrModel.new(self, column)
|
42
|
-
return CacheServiceFactory.has_cacher?(attr)
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def set_klass_to_mapping(attr, class_name)
|
48
|
-
ActiveSupport::Dependencies.onload(class_name || self.to_s) do
|
49
|
-
yield if CacheServiceFactory.set_klass_to_mapping(attr, self)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def get_expire_infos(attr, expire_by, foreign_key)
|
54
|
-
if expire_by.is_a?(Symbol)
|
55
|
-
expire_attr = get_association_attr(expire_by)
|
56
|
-
if expire_attr.join_table_class_name
|
57
|
-
expire_attr.klass.send(:"after_add_for_#{expire_by}") << gen_has_many_through_callback(attr.column)
|
58
|
-
expire_attr.klass.send(:"after_remove_for_#{expire_by}") << gen_has_many_through_callback(attr.column)
|
59
|
-
expire_by = expire_attr.join_table_class_name
|
60
|
-
else
|
61
|
-
expire_by = get_expire_by_from(expire_attr)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
expire_attr = attr
|
65
|
-
expire_by ||= get_expire_by_from(expire_attr)
|
66
|
-
end
|
67
|
-
return if expire_by == nil
|
68
|
-
|
69
|
-
class_name, column = expire_by.split('#', 2)
|
70
|
-
foreign_key ||= expire_attr.foreign_key(reverse: true) || 'id'
|
71
|
-
|
72
|
-
return class_name, column, foreign_key.to_s
|
73
|
-
end
|
74
|
-
|
75
|
-
NO_MACRO_FOR_AFTER_ADD = Gem::Version.new(::ActiveRecord::VERSION::STRING) < Gem::Version.new('4')
|
76
|
-
def gen_has_many_through_callback(column)
|
77
|
-
return ->(this, _that){ this.cacher.clean(column) } if NO_MACRO_FOR_AFTER_ADD
|
78
|
-
return ->(_, this, _that){ this.cacher.clean(column) }
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_association_attr(column)
|
82
|
-
attr = AttrModel.new(self, column)
|
83
|
-
raise "#{column} is not an association" if not attr.association?
|
84
|
-
return attr
|
85
|
-
end
|
86
|
-
|
87
|
-
def get_expire_by_from(attr)
|
88
|
-
return attr.class_name if attr.association?
|
89
|
-
return "#{self}##{attr.column}" if column_names.include?(attr.column.to_s)
|
90
|
-
end
|
91
|
-
|
92
|
-
def cache_belongs_to(attr)
|
93
|
-
service_klasses = [cache_at(attr.foreign_key)]
|
94
|
-
Cacher.define_cacher_method(attr, attr.primary_key, service_klasses)
|
95
|
-
ActiveSupport::Dependencies.onload(attr.class_name) do
|
96
|
-
service_klasses << cache_self
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
@global_callbacks = nil
|
101
|
-
def self.global_callbacks
|
102
|
-
if @global_callbacks == nil
|
103
|
-
global_callbacks = @global_callbacks = GlobalCallbacks.new
|
104
|
-
::ActiveRecord::Base.instance_exec do
|
105
|
-
after_commit ->{
|
106
|
-
global_callbacks.after_commit1.exec(self, self.class)
|
107
|
-
global_callbacks.after_commit2.exec(self, self.class)
|
108
|
-
}
|
109
|
-
after_touch ->{
|
110
|
-
global_callbacks.after_touch1.exec(self, self.class)
|
111
|
-
global_callbacks.after_touch2.exec(self, self.class)
|
112
|
-
}
|
113
|
-
end
|
114
|
-
end
|
115
|
-
return @global_callbacks
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_model_cachers/active_record/global_callbacks'
|
3
|
+
require 'active_model_cachers/active_record/attr_model'
|
4
|
+
require 'active_model_cachers/active_record/cacher'
|
5
|
+
require 'active_model_cachers/hook/dependencies'
|
6
|
+
require 'active_model_cachers/hook/associations'
|
7
|
+
require 'active_model_cachers/hook/on_model_delete'
|
8
|
+
|
9
|
+
module ActiveModelCachers
|
10
|
+
module ActiveRecord
|
11
|
+
module Extension
|
12
|
+
def cache_self(by: :id)
|
13
|
+
cache_at(nil, expire_by: self.name, primary_key: by, foreign_key: by)
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_at(column, query = nil, expire_by: nil, on: nil, foreign_key: nil, primary_key: nil)
|
17
|
+
attr = AttrModel.new(self, column, foreign_key: foreign_key, primary_key: primary_key)
|
18
|
+
return cache_belongs_to(attr) if attr.belongs_to?
|
19
|
+
|
20
|
+
loaded = false
|
21
|
+
class_name, *infos = get_expire_infos(attr, expire_by, foreign_key)
|
22
|
+
set_klass_to_mapping(attr, class_name) do
|
23
|
+
next if !loaded
|
24
|
+
cache_at(column, query, expire_by: expire_by, on: on, foreign_key: foreign_key, primary_key: primary_key)
|
25
|
+
end
|
26
|
+
loaded = true
|
27
|
+
|
28
|
+
query ||= ->(id){ attr.query_model(self, id) }
|
29
|
+
service_klass = CacheServiceFactory.create_for_active_model(attr, query)
|
30
|
+
Cacher.define_cacher_method(attr, attr.primary_key || :id, [service_klass])
|
31
|
+
|
32
|
+
if class_name
|
33
|
+
with_id = (expire_by.is_a?(Symbol) || query.parameters.size == 1)
|
34
|
+
service_klass.define_callback_for_cleaning_cache(class_name, *infos, with_id, on: on)
|
35
|
+
end
|
36
|
+
|
37
|
+
return service_klass
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_cacher?(column = nil)
|
41
|
+
attr = AttrModel.new(self, column)
|
42
|
+
return CacheServiceFactory.has_cacher?(attr)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_klass_to_mapping(attr, class_name)
|
48
|
+
ActiveSupport::Dependencies.onload(class_name || self.to_s) do
|
49
|
+
yield if CacheServiceFactory.set_klass_to_mapping(attr, self)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_expire_infos(attr, expire_by, foreign_key)
|
54
|
+
if expire_by.is_a?(Symbol)
|
55
|
+
expire_attr = get_association_attr(expire_by)
|
56
|
+
if expire_attr.join_table_class_name
|
57
|
+
expire_attr.klass.send(:"after_add_for_#{expire_by}") << gen_has_many_through_callback(attr.column)
|
58
|
+
expire_attr.klass.send(:"after_remove_for_#{expire_by}") << gen_has_many_through_callback(attr.column)
|
59
|
+
expire_by = expire_attr.join_table_class_name
|
60
|
+
else
|
61
|
+
expire_by = get_expire_by_from(expire_attr)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
expire_attr = attr
|
65
|
+
expire_by ||= get_expire_by_from(expire_attr)
|
66
|
+
end
|
67
|
+
return if expire_by == nil
|
68
|
+
|
69
|
+
class_name, column = expire_by.split('#', 2)
|
70
|
+
foreign_key ||= expire_attr.foreign_key(reverse: true) || 'id'
|
71
|
+
|
72
|
+
return class_name, column, foreign_key.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
NO_MACRO_FOR_AFTER_ADD = Gem::Version.new(::ActiveRecord::VERSION::STRING) < Gem::Version.new('4')
|
76
|
+
def gen_has_many_through_callback(column)
|
77
|
+
return ->(this, _that){ this.cacher.clean(column) } if NO_MACRO_FOR_AFTER_ADD
|
78
|
+
return ->(_, this, _that){ this.cacher.clean(column) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_association_attr(column)
|
82
|
+
attr = AttrModel.new(self, column)
|
83
|
+
raise "#{column} is not an association" if not attr.association?
|
84
|
+
return attr
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_expire_by_from(attr)
|
88
|
+
return attr.class_name if attr.association?
|
89
|
+
return "#{self}##{attr.column}" if column_names.include?(attr.column.to_s)
|
90
|
+
end
|
91
|
+
|
92
|
+
def cache_belongs_to(attr)
|
93
|
+
service_klasses = [cache_at(attr.foreign_key)]
|
94
|
+
Cacher.define_cacher_method(attr, attr.primary_key, service_klasses)
|
95
|
+
ActiveSupport::Dependencies.onload(attr.class_name) do
|
96
|
+
service_klasses << cache_self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
@global_callbacks = nil
|
101
|
+
def self.global_callbacks
|
102
|
+
if @global_callbacks == nil
|
103
|
+
global_callbacks = @global_callbacks = GlobalCallbacks.new
|
104
|
+
::ActiveRecord::Base.instance_exec do
|
105
|
+
after_commit ->{
|
106
|
+
global_callbacks.after_commit1.exec(self, self.class)
|
107
|
+
global_callbacks.after_commit2.exec(self, self.class)
|
108
|
+
}
|
109
|
+
after_touch ->{
|
110
|
+
global_callbacks.after_touch1.exec(self, self.class)
|
111
|
+
global_callbacks.after_touch2.exec(self, self.class)
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
return @global_callbacks
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -1,67 +1,67 @@
|
|
1
|
-
module ActiveModelCachers
|
2
|
-
module ActiveRecord
|
3
|
-
class GlobalCallbacks
|
4
|
-
def initialize
|
5
|
-
@type_callbacks = {}
|
6
|
-
end
|
7
|
-
|
8
|
-
def before_delete1(class_name = nil, &block)
|
9
|
-
define_callbacks(:before_delete1, class_name, &block)
|
10
|
-
end
|
11
|
-
|
12
|
-
def before_delete2(class_name = nil, &block)
|
13
|
-
define_callbacks(:before_delete2, class_name, &block)
|
14
|
-
end
|
15
|
-
|
16
|
-
def after_delete(class_name = nil, &block)
|
17
|
-
define_callbacks(:after_delete, class_name, &block)
|
18
|
-
end
|
19
|
-
|
20
|
-
def on_nullify(class_name = nil, &block)
|
21
|
-
define_callbacks(:on_nullify, class_name, &block)
|
22
|
-
end
|
23
|
-
|
24
|
-
def after_commit1(class_name = nil, &block)
|
25
|
-
define_callbacks(:after_commit1, class_name, &block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def after_commit2(class_name = nil, &block)
|
29
|
-
define_callbacks(:after_commit2, class_name, &block)
|
30
|
-
end
|
31
|
-
|
32
|
-
def after_touch1(class_name = nil, &block)
|
33
|
-
define_callbacks(:after_touch1, class_name, &block)
|
34
|
-
end
|
35
|
-
|
36
|
-
def after_touch2(class_name = nil, &block)
|
37
|
-
define_callbacks(:after_touch2, class_name, &block)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def define_callbacks(type, class_name, &block)
|
43
|
-
(@type_callbacks[type] ||= ClassCallbacks.new).tap do |s|
|
44
|
-
s.add_callback(class_name, &block) if class_name
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class ClassCallbacks
|
50
|
-
def initialize
|
51
|
-
@class_callbacks = Hash.new{|h, k| h[k] = [] }
|
52
|
-
end
|
53
|
-
|
54
|
-
def callbacks_at(class_name)
|
55
|
-
@class_callbacks[class_name]
|
56
|
-
end
|
57
|
-
|
58
|
-
def add_callback(class_name, &block)
|
59
|
-
callbacks_at(class_name) << block
|
60
|
-
end
|
61
|
-
|
62
|
-
def exec(scope, klass, *args)
|
63
|
-
callbacks_at(klass.name).each{|s| scope.instance_exec(*args, &s) }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
1
|
+
module ActiveModelCachers
|
2
|
+
module ActiveRecord
|
3
|
+
class GlobalCallbacks
|
4
|
+
def initialize
|
5
|
+
@type_callbacks = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def before_delete1(class_name = nil, &block)
|
9
|
+
define_callbacks(:before_delete1, class_name, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def before_delete2(class_name = nil, &block)
|
13
|
+
define_callbacks(:before_delete2, class_name, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def after_delete(class_name = nil, &block)
|
17
|
+
define_callbacks(:after_delete, class_name, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_nullify(class_name = nil, &block)
|
21
|
+
define_callbacks(:on_nullify, class_name, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def after_commit1(class_name = nil, &block)
|
25
|
+
define_callbacks(:after_commit1, class_name, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def after_commit2(class_name = nil, &block)
|
29
|
+
define_callbacks(:after_commit2, class_name, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def after_touch1(class_name = nil, &block)
|
33
|
+
define_callbacks(:after_touch1, class_name, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def after_touch2(class_name = nil, &block)
|
37
|
+
define_callbacks(:after_touch2, class_name, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def define_callbacks(type, class_name, &block)
|
43
|
+
(@type_callbacks[type] ||= ClassCallbacks.new).tap do |s|
|
44
|
+
s.add_callback(class_name, &block) if class_name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class ClassCallbacks
|
50
|
+
def initialize
|
51
|
+
@class_callbacks = Hash.new{|h, k| h[k] = [] }
|
52
|
+
end
|
53
|
+
|
54
|
+
def callbacks_at(class_name)
|
55
|
+
@class_callbacks[class_name]
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_callback(class_name, &block)
|
59
|
+
callbacks_at(class_name) << block
|
60
|
+
end
|
61
|
+
|
62
|
+
def exec(scope, klass, *args)
|
63
|
+
callbacks_at(klass.name).each{|s| scope.instance_exec(*args, &s) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|