rails_best_practices 1.19.2 → 1.20.1
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/.gitignore +0 -1
- data/.travis.yml +2 -3
- data/CHANGELOG.md +7 -7
- data/Gemfile +3 -5
- data/Gemfile.lock +125 -0
- data/Guardfile +2 -0
- data/README.md +6 -6
- data/Rakefile +2 -17
- data/assets/result.html.erb +2 -0
- data/lib/rails_best_practices.rb +3 -2
- data/lib/rails_best_practices/analyzer.rb +61 -49
- 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 +64 -56
- data/lib/rails_best_practices/core/checks_loader.rb +24 -23
- data/lib/rails_best_practices/core/configs.rb +1 -2
- data/lib/rails_best_practices/core/controllers.rb +1 -2
- data/lib/rails_best_practices/core/error.rb +1 -1
- data/lib/rails_best_practices/core/helpers.rb +1 -2
- data/lib/rails_best_practices/core/mailers.rb +1 -2
- data/lib/rails_best_practices/core/methods.rb +27 -21
- data/lib/rails_best_practices/core/model_associations.rb +10 -5
- data/lib/rails_best_practices/core/models.rb +1 -2
- data/lib/rails_best_practices/core/modules.rb +1 -1
- data/lib/rails_best_practices/core/routes.rb +2 -2
- data/lib/rails_best_practices/core/runner.rb +67 -73
- data/lib/rails_best_practices/lexicals/long_line_check.rb +7 -3
- data/lib/rails_best_practices/option_parser.rb +156 -0
- data/lib/rails_best_practices/prepares.rb +1 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +24 -17
- data/lib/rails_best_practices/prepares/gemfile_prepare.rb +2 -2
- data/lib/rails_best_practices/prepares/helper_prepare.rb +6 -1
- data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +2 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +63 -23
- data/lib/rails_best_practices/prepares/route_prepare.rb +28 -21
- data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +38 -34
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +94 -89
- data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +15 -5
- data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +20 -8
- 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 +16 -16
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +12 -12
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +10 -11
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +25 -24
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +4 -4
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +9 -10
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +10 -11
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +24 -22
- 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 +1 -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 +8 -8
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +35 -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 +26 -19
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +12 -10
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +38 -18
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +11 -11
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +77 -74
- data/lib/rails_best_practices/reviews/review.rb +2 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -3
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +12 -12
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +18 -15
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +15 -15
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +24 -22
- data/lib/rails_best_practices/reviews/use_observer_review.rb +28 -28
- 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 +68 -66
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +9 -8
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +16 -14
- data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +2 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +38 -43
- data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +1 -2
- data/spec/rails_best_practices/analyzer_spec.rb +73 -42
- data/spec/rails_best_practices/core/check_spec.rb +5 -5
- data/spec/rails_best_practices/core/checks_loader_spec.rb +3 -3
- data/spec/rails_best_practices/core/configs_spec.rb +1 -1
- data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
- data/spec/rails_best_practices/core/error_spec.rb +21 -18
- data/spec/rails_best_practices/core/except_methods_spec.rb +7 -7
- data/spec/rails_best_practices/core/gems_spec.rb +4 -4
- data/spec/rails_best_practices/core/helpers_spec.rb +1 -1
- data/spec/rails_best_practices/core/klasses_spec.rb +3 -3
- data/spec/rails_best_practices/core/mailers_spec.rb +1 -1
- data/spec/rails_best_practices/core/methods_spec.rb +6 -6
- data/spec/rails_best_practices/core/model_associations_spec.rb +10 -6
- data/spec/rails_best_practices/core/model_attributes_spec.rb +4 -4
- data/spec/rails_best_practices/core/models_spec.rb +1 -1
- data/spec/rails_best_practices/core/modules_spec.rb +5 -5
- data/spec/rails_best_practices/core/routes_spec.rb +5 -5
- data/spec/rails_best_practices/core/runner_spec.rb +9 -7
- data/spec/rails_best_practices/core_ext/erubis_spec.rb +10 -10
- data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +32 -31
- data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
- data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
- data/spec/rails_best_practices/prepares/config_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +18 -10
- data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +17 -17
- data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +79 -43
- data/spec/rails_best_practices/prepares/route_prepare_spec.rb +141 -76
- data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +18 -12
- data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +28 -22
- data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +15 -13
- data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +31 -21
- data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +13 -13
- data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +29 -22
- data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +11 -6
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +32 -22
- data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +9 -7
- data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +24 -17
- data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +64 -31
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +21 -14
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +57 -53
- data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +10 -8
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +20 -14
- data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +54 -31
- data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +13 -13
- data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +11 -9
- data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +35 -31
- data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +10 -8
- data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +31 -24
- data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +15 -11
- data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +14 -14
- data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +61 -59
- metadata +16 -18
@@ -28,40 +28,41 @@ module RailsBestPractices
|
|
28
28
|
# and the message of the receiver call node matchs one of the association name with the class name,
|
29
29
|
# then it violates the law of demeter.
|
30
30
|
add_callback :start_call do |node|
|
31
|
-
if
|
31
|
+
if node.receiver.sexp_type == :call && need_delegate?(node)
|
32
32
|
add_error 'law of demeter'
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
class_name = variable(node).to_s.sub('@', '').classify
|
46
|
-
association_name = node.receiver.message.to_s
|
47
|
-
association = model_associations.get_association(class_name, association_name)
|
48
|
-
attribute_name = node.message.to_s
|
49
|
-
association && ASSOCIATION_METHODS.include?(association['meta']) &&
|
50
|
-
is_association_attribute?(association['class_name'], association_name, attribute_name)
|
51
|
-
end
|
38
|
+
# check if the call node can use delegate to avoid violating law of demeter.
|
39
|
+
#
|
40
|
+
# if the receiver of receiver of the call node matchs any in model names,
|
41
|
+
# and the message of receiver of the call node matchs any in association names,
|
42
|
+
# then it needs delegate.
|
43
|
+
def need_delegate?(node)
|
44
|
+
return unless variable(node)
|
52
45
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
46
|
+
class_name = variable(node).to_s.sub('@', '').classify
|
47
|
+
association_name = node.receiver.message.to_s
|
48
|
+
association = model_associations.get_association(class_name, association_name)
|
49
|
+
attribute_name = node.message.to_s
|
50
|
+
association && ASSOCIATION_METHODS.include?(association['meta']) &&
|
51
|
+
is_association_attribute?(association['class_name'], association_name, attribute_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_association_attribute?(association_class, association_name, attribute_name)
|
55
|
+
if association_name =~ /able$/
|
56
|
+
models.each do |class_name|
|
57
|
+
if model_associations.is_association?(class_name, association_name.sub(/able$/, '')) ||
|
58
|
+
model_associations.is_association?(class_name, association_name.sub(/able$/, 's'))
|
59
|
+
return true if model_attributes.is_attribute?(class_name, attribute_name)
|
60
60
|
end
|
61
|
-
else
|
62
|
-
model_attributes.is_attribute?(association_class, attribute_name)
|
63
61
|
end
|
62
|
+
else
|
63
|
+
model_attributes.is_attribute?(association_class, attribute_name)
|
64
64
|
end
|
65
|
+
end
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
@@ -37,10 +37,10 @@ module RailsBestPractices
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
# check if the node is a finder call node.
|
41
|
+
def finder?(node)
|
42
|
+
node.receiver.const? && FINDERS.include?(node.message.to_s)
|
43
|
+
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -38,16 +38,15 @@ module RailsBestPractices
|
|
38
38
|
|
39
39
|
private
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
41
|
+
# check if the arguments of options_for_select are complex.
|
42
|
+
#
|
43
|
+
# if the first argument is an array,
|
44
|
+
# and the size of array is greater than @array_count you defined,
|
45
|
+
# then it is complext.
|
46
|
+
def complex_select_options?(node)
|
47
|
+
node[1].message.to_s == 'options_for_select' && node.arguments.all.first.sexp_type == :array &&
|
48
|
+
node.arguments.all.first.array_size > @array_count
|
49
|
+
end
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -29,17 +29,16 @@ module RailsBestPractices
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
32
|
+
# check if the method_add_arg node is a finder.
|
33
|
+
#
|
34
|
+
# if the receiver of method_add_arg node is a constant,
|
35
|
+
# and the message of call method_add_arg is one of find, all, first or last,
|
36
|
+
# and any of its arguments is a hash,
|
37
|
+
# then it is a finder.
|
38
|
+
def finder?(node)
|
39
|
+
FINDERS.include?(node[1].message.to_s) && node[1].sexp_type == :call &&
|
40
|
+
node.arguments.grep_nodes_count(sexp_type: :bare_assoc_hash) > 0
|
41
|
+
end
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -51,30 +51,32 @@ module RailsBestPractices
|
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@counter -= 1
|
74
|
-
elsif %i[command_call command].include?(node.sexp_type) && %w[resources resource].include?(node.message.to_s)
|
75
|
-
add_error "needless deep nesting (nested_count > #{@nested_count})", @file, node.line_number if @counter >= @nested_count && !@shallow_nodes.include?(node)
|
54
|
+
# check nested route.
|
55
|
+
#
|
56
|
+
# if the receiver of the method_add_block is with message "resources" or "resource",
|
57
|
+
# then increment the @counter, recursively check the block body, and decrement the @counter.
|
58
|
+
#
|
59
|
+
# if the node type is command_call or command,
|
60
|
+
# and its message is resources or resource,
|
61
|
+
# then check if @counter is greater than or equal to @nested_count,
|
62
|
+
# if so, it is the needless deep nesting.
|
63
|
+
def recursively_check(node)
|
64
|
+
shallow = @shallow_nodes.include? node
|
65
|
+
|
66
|
+
if %i[command_call command].include?(node[1].sexp_type) && %w[resources resource].include?(node[1].message.to_s)
|
67
|
+
hash_node = node[1].arguments.grep_node(sexp_type: :bare_assoc_hash)
|
68
|
+
shallow ||= (hash_node && hash_node.hash_value('shallow').to_s == 'true')
|
69
|
+
@counter += 1
|
70
|
+
node.block_node.statements.each do |stmt_node|
|
71
|
+
@shallow_nodes << stmt_node if shallow
|
72
|
+
recursively_check(stmt_node)
|
76
73
|
end
|
74
|
+
@counter -= 1
|
75
|
+
elsif %i[command_call command].include?(node.sexp_type) && %w[resources resource].include?(node.message.to_s)
|
76
|
+
add_error "needless deep nesting (nested_count > #{@nested_count})", @file, node.line_number if @counter >=
|
77
|
+
@nested_count && !@shallow_nodes.include?(node)
|
77
78
|
end
|
79
|
+
end
|
78
80
|
end
|
79
81
|
end
|
80
82
|
end
|
@@ -18,7 +18,7 @@ module RailsBestPractices
|
|
18
18
|
|
19
19
|
# check rescue node to see if its type is Exception
|
20
20
|
add_callback :start_rescue do |rescue_node|
|
21
|
-
if rescue_node.exception_classes.any? { |rescue_class| 'Exception'
|
21
|
+
if rescue_node.exception_classes.any? { |rescue_class| rescue_class.to_s == 'Exception' }
|
22
22
|
add_error "Don't rescue Exception", rescue_node.file, rescue_node.exception_classes.first.line_number
|
23
23
|
end
|
24
24
|
end
|
@@ -24,8 +24,7 @@ module RailsBestPractices
|
|
24
24
|
|
25
25
|
# check all command nodes
|
26
26
|
add_callback :start_command do |node|
|
27
|
-
if 'match'
|
28
|
-
':controller(/:action(/:id(.:format)))' == node.arguments.all.first.to_s
|
27
|
+
if node.message.to_s == 'match' && node.arguments.all.first.to_s == ':controller(/:action(/:id(.:format)))'
|
29
28
|
add_error 'not use default route'
|
30
29
|
end
|
31
30
|
end
|
@@ -17,7 +17,7 @@ module RailsBestPractices
|
|
17
17
|
|
18
18
|
# check fcall node to see if its message is time_ago_in_words or distance_of_time_in_words_to_now
|
19
19
|
add_callback :start_fcall do |node|
|
20
|
-
if
|
20
|
+
if node.message.to_s == 'time_ago_in_words' || node.message.to_s == 'distance_of_time_in_words_to_now'
|
21
21
|
add_error 'not use time_ago_in_words'
|
22
22
|
end
|
23
23
|
end
|
@@ -41,14 +41,14 @@ module RailsBestPractices
|
|
41
41
|
|
42
42
|
private
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
# check method_add_block node to calculate the count of member and collection custom routes.
|
45
|
+
#
|
46
|
+
# if its receiver is with message "resources",
|
47
|
+
# then calculate the count of call nodes, whose message is get, post, update or delete,
|
48
|
+
# it is just the count of member and collection custom routes.
|
49
|
+
def member_and_collection_count_for_rails3(node)
|
50
|
+
node[1].message.to_s == 'resources' ? node.grep_nodes_count(sexp_type: :command, message: VERBS) : 0
|
51
|
+
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -11,6 +11,7 @@ module RailsBestPractices
|
|
11
11
|
# Review process:
|
12
12
|
# check nodes to see if there is a command with message attr_accessible or attr_protected,
|
13
13
|
# or include ActiveModel::ForbiddenAttributesProtection.
|
14
|
+
|
14
15
|
class ProtectMassAssignmentReview < Review
|
15
16
|
interesting_files MODEL_FILES
|
16
17
|
interesting_nodes :class, :command, :var_ref, :vcall, :fcall
|
@@ -54,53 +55,55 @@ module RailsBestPractices
|
|
54
55
|
|
55
56
|
private
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
58
|
+
def check_activerecord_version
|
59
|
+
if Prepares.gems.gem_version('activerecord').to_i > 3
|
60
|
+
@mass_assignement = false
|
61
61
|
end
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
64
|
+
def check_whitelist_attributes_config
|
65
|
+
if Prepares.configs['config.active_record.whitelist_attributes'] == 'true'
|
66
|
+
@whitelist_attributes = true
|
67
67
|
end
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
70
|
+
def check_include_forbidden_attributes_protection_config
|
71
|
+
if Prepares.configs['railsbp.include_forbidden_attributes_protection'] == 'true'
|
72
|
+
@mass_assignement = false
|
73
73
|
end
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
def check_rails_builtin(node)
|
77
|
+
if @whitelist_attributes ||
|
78
|
+
[node.to_s, node.message.to_s].any? { |str| %w[attr_accessible attr_protected].include? str }
|
79
|
+
@mass_assignement = false
|
79
80
|
end
|
81
|
+
end
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
def check_strong_parameters(command_node)
|
84
|
+
if command_node.message.to_s == 'include' &&
|
85
|
+
command_node.arguments.all.first.to_s == 'ActiveModel::ForbiddenAttributesProtection'
|
86
|
+
@mass_assignement = false
|
85
87
|
end
|
88
|
+
end
|
86
89
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
90
|
+
def check_devise(command_node)
|
91
|
+
if command_node.message.to_s == 'devise'
|
92
|
+
@mass_assignement = false
|
91
93
|
end
|
94
|
+
end
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
96
|
+
def check_authlogic(node)
|
97
|
+
if [node.to_s, node.message.to_s].include? 'acts_as_authentic'
|
98
|
+
@mass_assignement = false
|
97
99
|
end
|
100
|
+
end
|
98
101
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
102
|
+
def check_active_record(const_path_ref_node)
|
103
|
+
if const_path_ref_node.base_class.to_s != 'ActiveRecord::Base'
|
104
|
+
@mass_assignement = false
|
103
105
|
end
|
106
|
+
end
|
104
107
|
end
|
105
108
|
end
|
106
109
|
end
|
@@ -17,16 +17,16 @@ module RailsBestPractices
|
|
17
17
|
|
18
18
|
# check the body of module node, if it is nil, then it should be removed.
|
19
19
|
add_callback :start_module do |module_node|
|
20
|
-
if
|
20
|
+
if module_node.module_name.to_s != 'ApplicationHelper' && empty_body?(module_node)
|
21
21
|
add_error 'remove empty helpers'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
protected
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
def empty_body?(module_node)
|
28
|
+
s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil) == module_node.body
|
29
|
+
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -11,6 +11,7 @@ module RailsBestPractices
|
|
11
11
|
# if they are not defined in routes,
|
12
12
|
# and they are not called in controllers,
|
13
13
|
# then they are the unused methods in controllers.
|
14
|
+
|
14
15
|
class RemoveUnusedMethodsInControllersReview < Review
|
15
16
|
include Classable
|
16
17
|
include Moduleable
|
@@ -30,11 +31,15 @@ module RailsBestPractices
|
|
30
31
|
@inherited_resources = false
|
31
32
|
end
|
32
33
|
|
34
|
+
add_callback :start_class do |_node|
|
35
|
+
@current_controller_name = @klass.to_s
|
36
|
+
end
|
37
|
+
|
33
38
|
# mark custom inherited_resources methods as used.
|
34
39
|
add_callback :end_class do |_node|
|
35
40
|
if @inherited_resources
|
36
41
|
INHERITED_RESOURCES_METHODS.each do |method|
|
37
|
-
call_method(method)
|
42
|
+
call_method(method, @current_controller_name)
|
38
43
|
end
|
39
44
|
end
|
40
45
|
end
|
@@ -56,7 +61,7 @@ module RailsBestPractices
|
|
56
61
|
action_name = first_argument.hash_value('state').to_s
|
57
62
|
call_method(action_name, current_class_name)
|
58
63
|
end
|
59
|
-
when 'around_filter'
|
64
|
+
when 'around_filter', 'around_action'
|
60
65
|
node.arguments.all.each { |argument| mark_used(argument) }
|
61
66
|
when 'layout'
|
62
67
|
first_argument = node.arguments.all.first
|
@@ -67,7 +72,7 @@ module RailsBestPractices
|
|
67
72
|
node.arguments.all.each { |argument| mark_publicize(argument.to_s) }
|
68
73
|
when 'delegate'
|
69
74
|
last_argument = node.arguments.all.last
|
70
|
-
if
|
75
|
+
if last_argument.sexp_type == :bare_assoc_hash && last_argument.hash_value('to').to_s == 'controller'
|
71
76
|
controller_name = current_module_name.sub('Helper', 'Controller')
|
72
77
|
node.arguments.all[0..-2].each { |method| mark_publicize(method.to_s, controller_name) }
|
73
78
|
end
|
@@ -78,7 +83,7 @@ module RailsBestPractices
|
|
78
83
|
|
79
84
|
# mark assignment as used, like current_user = @user
|
80
85
|
add_callback :start_assign do |node|
|
81
|
-
if
|
86
|
+
if node.left_value.sexp_type == :var_field
|
82
87
|
call_method "#{node.left_value}=", current_class_name
|
83
88
|
end
|
84
89
|
end
|
@@ -86,7 +91,7 @@ module RailsBestPractices
|
|
86
91
|
# get all unused methods at the end of review process.
|
87
92
|
add_callback :after_check do
|
88
93
|
@routes.each do |route|
|
89
|
-
if '*'
|
94
|
+
if route.action_name == '*'
|
90
95
|
action_names = @controller_methods.get_methods(route.controller_name_with_namespaces).map(&:method_name)
|
91
96
|
action_names.each { |action_name| call_method(action_name, route.controller_name_with_namespaces) }
|
92
97
|
else
|
@@ -94,27 +99,29 @@ module RailsBestPractices
|
|
94
99
|
end
|
95
100
|
end
|
96
101
|
@controller_methods.get_all_unused_methods.each do |method|
|
97
|
-
|
98
|
-
|
99
|
-
|
102
|
+
next if excepted?(method)
|
103
|
+
|
104
|
+
add_error "remove unused methods (#{method.class_name}##{method.method_name})",
|
105
|
+
method.file,
|
106
|
+
method.line_number
|
100
107
|
end
|
101
108
|
end
|
102
109
|
|
103
110
|
protected
|
104
111
|
|
105
|
-
|
106
|
-
|
107
|
-
|
112
|
+
def methods
|
113
|
+
@controller_methods
|
114
|
+
end
|
108
115
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
116
|
+
def internal_except_methods
|
117
|
+
%w[rescue_action default_url_options].map { |method_name| "*\##{method_name}" } +
|
118
|
+
%w[Devise::OmniauthCallbacksController].map { |controller_name| "#{controller_name}#*" }
|
119
|
+
end
|
113
120
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
121
|
+
def mark_publicize(method_name, class_name = current_class_name)
|
122
|
+
@controller_methods.mark_publicize(class_name, method_name)
|
123
|
+
@controller_methods.mark_parent_class_methods_publicize(class_name, method_name)
|
124
|
+
end
|
118
125
|
end
|
119
126
|
end
|
120
127
|
end
|