rails_best_practices 1.19.3 → 1.19.4
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 +4 -4
- data/.gitignore +0 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile +0 -4
- data/Gemfile.lock +120 -0
- data/README.md +4 -1
- data/lib/rails_best_practices.rb +2 -0
- data/lib/rails_best_practices/analyzer.rb +5 -4
- data/lib/rails_best_practices/cli.rb +22 -0
- data/lib/rails_best_practices/command.rb +1 -131
- data/lib/rails_best_practices/core/check.rb +24 -23
- data/lib/rails_best_practices/core/checks_loader.rb +17 -18
- data/lib/rails_best_practices/core/methods.rb +9 -8
- data/lib/rails_best_practices/core/model_associations.rb +1 -1
- data/lib/rails_best_practices/core/runner.rb +38 -38
- data/lib/rails_best_practices/option_parser.rb +140 -0
- data/lib/rails_best_practices/prepares/controller_prepare.rb +8 -14
- data/lib/rails_best_practices/prepares/gemfile_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +13 -13
- data/lib/rails_best_practices/prepares/route_prepare.rb +16 -15
- data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +25 -23
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +73 -72
- data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +2 -1
- data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +4 -3
- data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +1 -1
- data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +1 -1
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +11 -11
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +8 -8
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +5 -5
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +20 -19
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +3 -3
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +5 -5
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +5 -5
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +13 -13
- data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +1 -1
- data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +2 -2
- data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +1 -1
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +3 -3
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +32 -32
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -4
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +14 -14
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +6 -6
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +15 -15
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +8 -8
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +71 -70
- data/lib/rails_best_practices/reviews/review.rb +2 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +1 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +11 -11
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +12 -9
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +10 -10
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +14 -13
- data/lib/rails_best_practices/reviews/use_observer_review.rb +20 -20
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +6 -6
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +44 -41
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +7 -7
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +14 -14
- data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +1 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +8 -8
- data/spec/rails_best_practices/analyzer_spec.rb +4 -4
- data/spec/rails_best_practices/core/error_spec.rb +6 -3
- data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +21 -21
- data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +15 -15
- data/spec/rails_best_practices/prepares/route_prepare_spec.rb +17 -15
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +4 -2
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +6 -4
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +8 -6
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +16 -14
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +14 -14
- data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +1 -1
- data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +51 -51
- metadata +5 -2
data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb
CHANGED
@@ -37,7 +37,7 @@ module RailsBestPractices
|
|
37
37
|
node.recursive_children do |child_node|
|
38
38
|
case child_node.sexp_type
|
39
39
|
when :assign
|
40
|
-
if
|
40
|
+
if child_node.receiver[2] == :"."
|
41
41
|
remember_variable_use_count(child_node)
|
42
42
|
end
|
43
43
|
when :call
|
@@ -52,15 +52,15 @@ module RailsBestPractices
|
|
52
52
|
# check the call node to see if it is with message "save" or "save!",
|
53
53
|
# and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
|
54
54
|
# then it is a complex creation, should be replaced with factory method.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
55
|
+
def check_variable_save(node)
|
56
|
+
if ['save', 'save!'].include? node.message.to_s
|
57
|
+
variable = node.receiver.to_s
|
58
|
+
if variable_use_count[variable].to_i > @assigns_count
|
59
|
+
hint = "#{variable} attribute_assignment_count > #{@assigns_count}"
|
60
|
+
add_error "replace complex creation with factory method (#{hint})"
|
62
61
|
end
|
63
62
|
end
|
63
|
+
end
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -38,23 +38,23 @@ module RailsBestPractices
|
|
38
38
|
|
39
39
|
# check if the generated routes have the corresponding actions in controller for rails routes.
|
40
40
|
add_callback :start_command, :start_command_call do |node|
|
41
|
-
if
|
41
|
+
if node.message.to_s == 'resources'
|
42
42
|
if (mod = module_option(node))
|
43
43
|
@namespaces << mod
|
44
44
|
end
|
45
45
|
check_resources(node)
|
46
46
|
@resource_controllers << node.arguments.all.first.to_s
|
47
|
-
elsif
|
47
|
+
elsif node.message.to_s == 'resource'
|
48
48
|
check_resource(node)
|
49
49
|
@resource_controllers << node.arguments.all.first.to_s
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
add_callback :end_command do |node|
|
54
|
-
if
|
54
|
+
if node.message.to_s == 'resources'
|
55
55
|
@resource_controllers.pop
|
56
56
|
@namespaces.pop if module_option(node)
|
57
|
-
elsif
|
57
|
+
elsif node.message.to_s == 'resource'
|
58
58
|
@resource_controllers.pop
|
59
59
|
end
|
60
60
|
end
|
@@ -90,103 +90,104 @@ module RailsBestPractices
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def check_method_add_block?(node)
|
93
|
-
|
93
|
+
node[1].sexp_type == :command || (node[1].sexp_type == :command_call && node.receiver.to_s != 'map')
|
94
94
|
end
|
95
95
|
|
96
96
|
private
|
97
97
|
|
98
98
|
# check resources call, if the routes generated by resources does not exist in the controller.
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
def check_resources(node)
|
100
|
+
_check(node, resources_methods)
|
101
|
+
end
|
102
102
|
|
103
103
|
# check resource call, if the routes generated by resources does not exist in the controller.
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
def check_resource(node)
|
105
|
+
_check(node, resource_methods)
|
106
|
+
end
|
107
107
|
|
108
108
|
# get the controller name.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
else
|
115
|
-
name = node.arguments.all.first.to_s.gsub('::', '').tableize
|
116
|
-
end
|
109
|
+
def controller_name(node)
|
110
|
+
if option_with_hash(node)
|
111
|
+
option_node = node.arguments.all[1]
|
112
|
+
if hash_key_exist?(option_node, 'controller')
|
113
|
+
name = option_node.hash_value('controller').to_s
|
117
114
|
else
|
118
115
|
name = node.arguments.all.first.to_s.gsub('::', '').tableize
|
119
116
|
end
|
120
|
-
|
117
|
+
else
|
118
|
+
name = node.arguments.all.first.to_s.gsub('::', '').tableize
|
121
119
|
end
|
120
|
+
namespaced_class_name(name)
|
121
|
+
end
|
122
122
|
|
123
123
|
# get the class name with namespace.
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
124
|
+
def namespaced_class_name(name)
|
125
|
+
class_name = "#{name.split('/').map(&:camelize).join('::')}Controller"
|
126
|
+
if @namespaces.empty?
|
127
|
+
class_name
|
128
|
+
else
|
129
|
+
@namespaces.map { |namespace| "#{namespace.camelize}::" }.join('') + class_name
|
131
130
|
end
|
131
|
+
end
|
132
132
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
133
|
+
def _check(node, methods)
|
134
|
+
controller_name = controller_name(node)
|
135
|
+
return unless Prepares.controllers.include? controller_name
|
136
|
+
|
137
|
+
_methods = _methods(node, methods)
|
138
|
+
unless _methods.all? { |meth| Prepares.controller_methods.has_method?(controller_name, meth) }
|
139
|
+
prepared_method_names = Prepares.controller_methods.get_methods(controller_name).map(&:method_name)
|
140
|
+
only_methods = (_methods & prepared_method_names).map { |meth| ":#{meth}" }
|
141
|
+
routes_message = if only_methods.size > 3
|
142
|
+
"except: [#{(methods.map { |meth| ':' + meth } - only_methods).join(', ')}]"
|
143
|
+
else
|
144
|
+
"only: [#{only_methods.join(', ')}]"
|
145
|
+
end
|
146
|
+
add_error "restrict auto-generated routes #{friendly_route_name(node)} (#{routes_message})"
|
147
147
|
end
|
148
|
+
end
|
148
149
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
else
|
158
|
-
(methods - Array(option_node.hash_value('except').to_object))
|
159
|
-
end
|
150
|
+
def _methods(node, methods)
|
151
|
+
if option_with_hash(node)
|
152
|
+
option_node = node.arguments.all[1]
|
153
|
+
if hash_key_exist?(option_node, 'only')
|
154
|
+
option_node.hash_value('only').to_s == 'none' ? [] : Array(option_node.hash_value('only').to_object)
|
155
|
+
elsif hash_key_exist?(option_node, 'except')
|
156
|
+
if option_node.hash_value('except').to_s == 'all'
|
157
|
+
[]
|
160
158
|
else
|
161
|
-
methods
|
159
|
+
(methods - Array(option_node.hash_value('except').to_object))
|
162
160
|
end
|
163
161
|
else
|
164
162
|
methods
|
165
163
|
end
|
164
|
+
else
|
165
|
+
methods
|
166
166
|
end
|
167
|
+
end
|
167
168
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
169
|
+
def module_option(node)
|
170
|
+
option_node = node.arguments[1].last
|
171
|
+
if option_node && option_node.sexp_type == :bare_assoc_hash && hash_key_exist?(option_node, 'module')
|
172
|
+
option_node.hash_value('module').to_s
|
173
173
|
end
|
174
|
+
end
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
|
176
|
+
def option_with_hash(node)
|
177
|
+
node.arguments.all.size > 1 && node.arguments.all[1].sexp_type == :bare_assoc_hash
|
178
|
+
end
|
178
179
|
|
179
|
-
|
180
|
-
|
181
|
-
|
180
|
+
def hash_key_exist?(node, key)
|
181
|
+
node.hash_keys && node.hash_keys.include?(key)
|
182
|
+
end
|
182
183
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
end
|
184
|
+
def friendly_route_name(node)
|
185
|
+
if @resource_controllers.last == node.arguments.to_s
|
186
|
+
[@namespaces.join('/'), @resource_controllers.join('/')].delete_if(&:blank?).join('/')
|
187
|
+
else
|
188
|
+
[@namespaces.join('/'), @resource_controllers.join('/'), node.arguments.to_s].delete_if(&:blank?).join('/')
|
189
189
|
end
|
190
|
+
end
|
190
191
|
end
|
191
192
|
end
|
192
193
|
end
|
@@ -13,7 +13,7 @@ module RailsBestPractices
|
|
13
13
|
# then save it to as key in @variable_use_count hash, and add the call count (hash value).
|
14
14
|
def remember_variable_use_count(node)
|
15
15
|
variable_node = variable(node)
|
16
|
-
if variable_node && 'self'
|
16
|
+
if variable_node && variable_node.to_s != 'self' && @last_variable_node != variable_node
|
17
17
|
@last_variable_node = variable_node
|
18
18
|
variable_use_count[variable_node.to_s] ||= 0
|
19
19
|
variable_use_count[variable_node.to_s] += 1
|
@@ -36,6 +36,7 @@ module RailsBestPractices
|
|
36
36
|
node = node.receiver
|
37
37
|
end
|
38
38
|
return if %i[fcall hash].include?(node.receiver.sexp_type)
|
39
|
+
|
39
40
|
node.receiver
|
40
41
|
end
|
41
42
|
|
@@ -21,7 +21,7 @@ module RailsBestPractices
|
|
21
21
|
# if its message is render and the arguments contain a key action, template or file,
|
22
22
|
# then it should be replaced by simplified syntax.
|
23
23
|
add_callback :start_command do |node|
|
24
|
-
if
|
24
|
+
if node.message.to_s == 'render'
|
25
25
|
keys = node.arguments.all.first.hash_keys
|
26
26
|
if keys && keys.size == 1 &&
|
27
27
|
(keys.include?('action') || keys.include?('template') || keys.include?('file'))
|
@@ -22,10 +22,10 @@ module RailsBestPractices
|
|
22
22
|
# if its message is render and the arguments contain a key partial,
|
23
23
|
# then it should be replaced by simplified syntax.
|
24
24
|
add_callback :start_command do |node|
|
25
|
-
if
|
25
|
+
if node.message.to_s == 'render'
|
26
26
|
hash_node = node.arguments.all.first
|
27
|
-
if hash_node &&
|
28
|
-
|
27
|
+
if hash_node && hash_node.sexp_type == :bare_assoc_hash &&
|
28
|
+
include_partial?(hash_node) && valid_hash?(hash_node)
|
29
29
|
add_error 'simplify render in views'
|
30
30
|
end
|
31
31
|
end
|
@@ -33,15 +33,15 @@ module RailsBestPractices
|
|
33
33
|
|
34
34
|
protected
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def include_partial?(hash_node)
|
37
|
+
hash_node.hash_keys.include?('partial') && !hash_node.hash_value('partial').to_s.include?('/')
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def valid_hash?(hash_node)
|
41
|
+
keys = hash_node.hash_keys
|
42
|
+
keys.delete('partial')
|
43
|
+
(keys - VALID_KEYS).empty?
|
44
|
+
end
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -34,10 +34,12 @@ module RailsBestPractices
|
|
34
34
|
var_ref_or_vcall_included = %i[var_ref vcall].include?(statement_node.sexp_type)
|
35
35
|
private_or_protected_included = %w[protected private].include?(statement_node.to_s)
|
36
36
|
break if var_ref_or_vcall_included && private_or_protected_included
|
37
|
-
|
37
|
+
|
38
|
+
remember_first_sentence(statement_node) if statement_node.sexp_type == :def
|
38
39
|
end
|
39
40
|
@first_sentences.each do |_first_sentence, def_nodes|
|
40
41
|
next unless def_nodes.size > @customize_count
|
42
|
+
|
41
43
|
add_error "use before_filter for #{def_nodes.map { |node| node.method_name.to_s }.join(',')}",
|
42
44
|
node.file,
|
43
45
|
def_nodes.map(&:line_number).join(',')
|
@@ -47,15 +49,16 @@ module RailsBestPractices
|
|
47
49
|
private
|
48
50
|
|
49
51
|
# check method define node, and remember the first sentence.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
def remember_first_sentence(node)
|
53
|
+
first_sentence = node.body.statements.first
|
54
|
+
return unless first_sentence
|
55
|
+
|
56
|
+
first_sentence = first_sentence.remove_line_and_column
|
57
|
+
unless first_sentence == s(:nil)
|
58
|
+
@first_sentences[first_sentence] ||= []
|
59
|
+
@first_sentences[first_sentence] << node
|
58
60
|
end
|
61
|
+
end
|
59
62
|
end
|
60
63
|
end
|
61
64
|
end
|
@@ -45,22 +45,22 @@ module RailsBestPractices
|
|
45
45
|
|
46
46
|
# check an attribute assignment node, if its message is xxx_id,
|
47
47
|
# then remember the receiver of the attribute assignment in @assignments.
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
48
|
+
def attribute_assignment(node)
|
49
|
+
if node.left_value.message.to_s =~ /_id$/
|
50
|
+
receiver = node.left_value.receiver.to_s
|
51
|
+
@assignments[receiver] = true
|
53
52
|
end
|
53
|
+
end
|
54
54
|
|
55
55
|
# check a call node with message "save" or "save!",
|
56
56
|
# if the receiver of call node exists in @assignments,
|
57
57
|
# then the attribute assignment should be replaced by using model association.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
58
|
+
def call_assignment(node)
|
59
|
+
if ['save', 'save!'].include? node.message.to_s
|
60
|
+
receiver = node.receiver.to_s
|
61
|
+
add_error "use model association (for #{receiver})" if @assignments[receiver]
|
63
62
|
end
|
63
|
+
end
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb
CHANGED
@@ -34,27 +34,28 @@ module RailsBestPractices
|
|
34
34
|
# check if rails's syntax mailer views are canonical.
|
35
35
|
#
|
36
36
|
# @param [String] name method name in action_mailer
|
37
|
-
|
37
|
+
def rails_canonical_mailer_views?(name); end
|
38
38
|
|
39
39
|
# check if rails3's syntax mailer views are canonical.
|
40
40
|
#
|
41
41
|
# @param [String] name method name in action_mailer
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
def rails3_canonical_mailer_views?(name)
|
43
|
+
return true if mailer_files(name).empty?
|
44
|
+
return true if mailer_files(name).none? { |filename| filename.index 'html' }
|
45
|
+
|
46
|
+
mailer_files(name).any? { |filename| filename.index 'html' } &&
|
47
|
+
mailer_files(name).any? { |filename| filename.index 'text' }
|
48
|
+
end
|
48
49
|
|
49
50
|
# all mail view files for a method name.
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
def mailer_files(name)
|
52
|
+
Dir.entries(mailer_directory) { |filename| filename.index name.to_s }
|
53
|
+
end
|
53
54
|
|
54
55
|
# the view directory of mailer.
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
def mailer_directory
|
57
|
+
File.join(Core::Runner.base_path, "app/views/#{@klazz_name.to_s.underscore}")
|
58
|
+
end
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
@@ -51,40 +51,40 @@ module RailsBestPractices
|
|
51
51
|
|
52
52
|
# check a command node, if it is a callback definition, such as after_create, before_create,
|
53
53
|
# then save the callback methods in @callbacks
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
54
|
+
def remember_callback(node)
|
55
|
+
if node.message.to_s =~ /^after_|^before_/
|
56
|
+
node.arguments.all.each do |argument|
|
57
|
+
# ignore callback like after_create Comment.new
|
58
|
+
@callbacks << argument.to_s if argument.sexp_type == :symbol_literal
|
60
59
|
end
|
61
60
|
end
|
61
|
+
end
|
62
62
|
|
63
63
|
# check a defn node to see if the method name exists in the @callbacks.
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
def callback_method?(node)
|
65
|
+
@callbacks.find { |callback| callback == node.method_name.to_s }
|
66
|
+
end
|
67
67
|
|
68
68
|
# check a def node to see if it contains a actionmailer deliver call.
|
69
69
|
#
|
70
70
|
# if the message of call node is deliver,
|
71
71
|
# and the receiver of the call node is with receiver node who exists in @callbacks,
|
72
72
|
# then the call node is actionmailer deliver call.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
73
|
+
def deliver_mailer?(node)
|
74
|
+
node.grep_nodes(sexp_type: :call) do |child_node|
|
75
|
+
if child_node.message.to_s == 'deliver'
|
76
|
+
if child_node.receiver.sexp_type == :method_add_arg &&
|
77
|
+
mailers.include?(child_node.receiver[1].receiver.to_s)
|
78
|
+
return true
|
80
79
|
end
|
81
80
|
end
|
82
|
-
false
|
83
81
|
end
|
82
|
+
false
|
83
|
+
end
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
def mailers
|
86
|
+
@mailers ||= Prepares.mailers
|
87
|
+
end
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|