rails_best_practices 1.10.1 → 1.11.0
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.
- data/.gitignore +1 -0
- data/README.md +11 -6
- data/assets/result.html.erb +76 -46
- data/install_supported_rubies.sh +3 -0
- data/lib/rails_best_practices.rb +2 -1
- data/lib/rails_best_practices/analyzer.rb +10 -8
- data/lib/rails_best_practices/core.rb +0 -4
- data/lib/rails_best_practices/core/check.rb +41 -117
- data/lib/rails_best_practices/core/error.rb +3 -9
- data/lib/rails_best_practices/core/runner.rb +20 -80
- data/lib/rails_best_practices/lexicals/long_line_check.rb +2 -1
- data/lib/rails_best_practices/lexicals/remove_tab_check.rb +1 -3
- data/lib/rails_best_practices/lexicals/remove_trailing_whitespace_check.rb +1 -3
- data/lib/rails_best_practices/prepares/config_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +7 -8
- data/lib/rails_best_practices/prepares/helper_prepare.rb +2 -2
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +6 -7
- data/lib/rails_best_practices/prepares/route_prepare.rb +12 -13
- data/lib/rails_best_practices/prepares/schema_prepare.rb +2 -2
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +19 -15
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +10 -17
- data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +2 -5
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +3 -30
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +7 -10
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +5 -9
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +10 -13
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +6 -9
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +2 -5
- data/lib/rails_best_practices/reviews/move_code_into_model_review.rb +7 -13
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +3 -6
- data/lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb +6 -9
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +3 -6
- data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +4 -7
- data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +2 -5
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +7 -10
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +2 -5
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +2 -5
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +8 -6
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +1 -2
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +4 -5
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +9 -12
- data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb +2 -13
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +18 -26
- data/lib/rails_best_practices/reviews/review.rb +6 -7
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -5
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +2 -5
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +2 -5
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +11 -14
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +11 -8
- data/lib/rails_best_practices/reviews/use_observer_review.rb +8 -11
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +1 -1
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +12 -18
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +7 -10
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +4 -10
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +1 -1
- data/rails_best_practices.yml +5 -5
- data/spec/rails_best_practices/core/check_spec.rb +0 -67
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +0 -1
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +0 -4
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +3 -30
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +22 -0
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +19 -0
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -4
- metadata +28 -41
- data/Gemfile.lock +0 -71
- data/lib/rails_best_practices/core/checking_visitor.rb +0 -80
- data/lib/rails_best_practices/core/nil.rb +0 -37
- data/lib/rails_best_practices/core_ext/enumerable.rb +0 -9
- data/lib/rails_best_practices/core_ext/sexp.rb +0 -840
- data/spec/rails_best_practices/core/checking_visitor_spec.rb +0 -79
- data/spec/rails_best_practices/core/nil_spec.rb +0 -37
- data/spec/rails_best_practices/core_ext/enumerable_spec.rb +0 -7
- data/spec/rails_best_practices/core_ext/sexp_spec.rb +0 -613
@@ -10,28 +10,25 @@ module RailsBestPractices
|
|
10
10
|
# Implementation:
|
11
11
|
#
|
12
12
|
# Review process:
|
13
|
-
# check if, unless, elsif there are multiple method calls or attribute assignments apply to one
|
14
|
-
# and the
|
13
|
+
# check if, unless, elsif there are multiple method calls or attribute assignments apply to one receiver,
|
14
|
+
# and the receiver is a variable, then they should be moved into model.
|
15
15
|
class MoveCodeIntoModelReview < Review
|
16
16
|
interesting_nodes :if, :unless, :elsif
|
17
17
|
interesting_files VIEW_FILES
|
18
|
-
|
19
|
-
def url
|
20
|
-
"http://rails-bestpractices.com/posts/25-move-code-into-model"
|
21
|
-
end
|
18
|
+
url "http://rails-bestpractices.com/posts/25-move-code-into-model"
|
22
19
|
|
23
20
|
def initialize(options={})
|
24
21
|
super()
|
25
22
|
@use_count = options['use_count'] || 2
|
26
23
|
end
|
27
24
|
|
28
|
-
# check if node to see whose conditional statementnodes contain multiple call nodes with same
|
25
|
+
# check if node to see whose conditional statementnodes contain multiple call nodes with same receiver who is a variable.
|
29
26
|
#
|
30
27
|
# it will check every call and assignment nodes in the conditional statement nodes.
|
31
28
|
#
|
32
|
-
# if there are multiple call and assignment nodes who have the same
|
33
|
-
# and the
|
34
|
-
|
29
|
+
# if there are multiple call and assignment nodes who have the same receiver,
|
30
|
+
# and the receiver is a variable, then the conditional statement nodes should be moved into model.
|
31
|
+
add_callback :start_if, :start_unless, :start_elsif do |node|
|
35
32
|
node.conditional_statement.grep_nodes(sexp_type: :call) { |child_node| remember_variable_use_count(child_node) }
|
36
33
|
|
37
34
|
variable_use_count.each do |variable_node, count|
|
@@ -40,9 +37,6 @@ module RailsBestPractices
|
|
40
37
|
|
41
38
|
reset_variable_use_count
|
42
39
|
end
|
43
|
-
|
44
|
-
alias_method :start_unless, :start_if
|
45
|
-
alias_method :start_elsif, :start_if
|
46
40
|
end
|
47
41
|
end
|
48
42
|
end
|
@@ -17,24 +17,21 @@ module RailsBestPractices
|
|
17
17
|
class MoveFinderToNamedScopeReview < Review
|
18
18
|
interesting_nodes :method_add_arg
|
19
19
|
interesting_files CONTROLLER_FILES
|
20
|
+
url "http://rails-bestpractices.com/posts/1-move-finder-to-named_scope"
|
20
21
|
|
21
22
|
FINDERS = %w(find all first last)
|
22
23
|
|
23
|
-
def url
|
24
|
-
"http://rails-bestpractices.com/posts/1-move-finder-to-named_scope"
|
25
|
-
end
|
26
|
-
|
27
24
|
# check method_add_ag node if its message is one of find, all, first or last,
|
28
25
|
# and it has a hash argument,
|
29
26
|
# then the call node is the finder that should be moved to model's named_scope.
|
30
|
-
|
27
|
+
add_callback :start_method_add_arg do |node|
|
31
28
|
add_error "move finder to named_scope" if finder?(node)
|
32
29
|
end
|
33
30
|
|
34
31
|
private
|
35
32
|
# check if the method_add_arg node is a finder.
|
36
33
|
#
|
37
|
-
# if the
|
34
|
+
# if the receiver of method_add_arg node is a constant,
|
38
35
|
# and the message of call method_add_arg is one of find, all, first or last,
|
39
36
|
# and any of its arguments is a hash,
|
40
37
|
# then it is a finder.
|
@@ -11,16 +11,13 @@ module RailsBestPractices
|
|
11
11
|
#
|
12
12
|
# Review process:
|
13
13
|
# check all method defines in the controller files,
|
14
|
-
# if there are multiple method calls apply to one
|
15
|
-
# and the
|
14
|
+
# if there are multiple method calls apply to one receiver,
|
15
|
+
# and the receiver is a variable,
|
16
16
|
# then they are complex model logic, and they should be moved into model.
|
17
17
|
class MoveModelLogicIntoModelReview < Review
|
18
18
|
interesting_nodes :def
|
19
19
|
interesting_files CONTROLLER_FILES
|
20
|
-
|
21
|
-
def url
|
22
|
-
"http://rails-bestpractices.com/posts/7-move-model-logic-into-the-model"
|
23
|
-
end
|
20
|
+
url "http://rails-bestpractices.com/posts/7-move-model-logic-into-the-model"
|
24
21
|
|
25
22
|
def initialize(options = {})
|
26
23
|
super()
|
@@ -30,10 +27,10 @@ module RailsBestPractices
|
|
30
27
|
# check method define node to see if there are multiple method calls on one varialbe.
|
31
28
|
#
|
32
29
|
# it will check every call nodes,
|
33
|
-
# if there are multiple call nodes who have the same
|
34
|
-
# and the
|
30
|
+
# if there are multiple call nodes who have the same receiver,
|
31
|
+
# and the receiver is a variable,
|
35
32
|
# then these method calls and attribute assignments should be moved into model.
|
36
|
-
|
33
|
+
add_callback :start_def do |node|
|
37
34
|
node.grep_nodes(sexp_type: [:call, :assign]) do |child_node|
|
38
35
|
remember_variable_use_count(child_node)
|
39
36
|
end
|
@@ -26,10 +26,7 @@ module RailsBestPractices
|
|
26
26
|
class NeedlessDeepNestingReview < Review
|
27
27
|
interesting_nodes :method_add_block
|
28
28
|
interesting_files ROUTE_FILES
|
29
|
-
|
30
|
-
def url
|
31
|
-
"http://rails-bestpractices.com/posts/11-needless-deep-nesting"
|
32
|
-
end
|
29
|
+
url "http://rails-bestpractices.com/posts/11-needless-deep-nesting"
|
33
30
|
|
34
31
|
def initialize(options = {})
|
35
32
|
super()
|
@@ -48,7 +45,7 @@ module RailsBestPractices
|
|
48
45
|
# if the child node is a command_call or command node with message "resources" or "resource",
|
49
46
|
# test if the @counter is greater than or equal to @nested_count,
|
50
47
|
# if so, it is a needless deep nesting.
|
51
|
-
|
48
|
+
add_callback :start_method_add_block do |node|
|
52
49
|
@file = node.file
|
53
50
|
recursively_check(node)
|
54
51
|
end
|
@@ -56,7 +53,7 @@ module RailsBestPractices
|
|
56
53
|
private
|
57
54
|
# check nested route.
|
58
55
|
#
|
59
|
-
# if the
|
56
|
+
# if the receiver of the method_add_block is with message "resources" or "resource",
|
60
57
|
# then increment the @counter, recursively check the block body, and decrement the @counter.
|
61
58
|
#
|
62
59
|
# if the node type is command_call or command,
|
@@ -21,14 +21,11 @@ module RailsBestPractices
|
|
21
21
|
class NotUseDefaultRouteReview < Review
|
22
22
|
interesting_nodes :command_call, :command
|
23
23
|
interesting_files ROUTE_FILES
|
24
|
-
|
25
|
-
def url
|
26
|
-
"http://rails-bestpractices.com/posts/12-not-use-default-route-if-you-use-restful-design"
|
27
|
-
end
|
24
|
+
url "http://rails-bestpractices.com/posts/12-not-use-default-route-if-you-use-restful-design"
|
28
25
|
|
29
26
|
# check all command call nodes, compare with rails2 default route
|
30
|
-
|
31
|
-
if "map" == node.
|
27
|
+
add_callback :start_command_call do |node|
|
28
|
+
if "map" == node.receiver.to_s && "connect" == node.message.to_s &&
|
32
29
|
(":controller/:action/:id" == node.arguments.all.first.to_s ||
|
33
30
|
":controller/:action/:id.:format" == node.arguments.all.first.to_s)
|
34
31
|
add_error "not use default route"
|
@@ -36,7 +33,7 @@ module RailsBestPractices
|
|
36
33
|
end
|
37
34
|
|
38
35
|
# check all command nodes, compare with rails3 default route
|
39
|
-
|
36
|
+
add_callback :start_command do |node|
|
40
37
|
if "match" == node.message.to_s &&
|
41
38
|
":controller(/:action(/:id(.:format)))" == node.arguments.all.first.to_s
|
42
39
|
add_error "not use default route"
|
@@ -14,13 +14,10 @@ module RailsBestPractices
|
|
14
14
|
class NotUseTimeAgoInWordsReview < Review
|
15
15
|
interesting_nodes :fcall
|
16
16
|
interesting_files VIEW_FILES, HELPER_FILES
|
17
|
-
|
18
|
-
def url
|
19
|
-
"http://rails-bestpractices.com/posts/105-not-use-time_ago_in_words"
|
20
|
-
end
|
17
|
+
url "http://rails-bestpractices.com/posts/105-not-use-time_ago_in_words"
|
21
18
|
|
22
19
|
# check fcall node to see if its message is time_ago_in_words or distance_of_time_in_words_to_now
|
23
|
-
|
20
|
+
add_callback :start_fcall do |node|
|
24
21
|
if "time_ago_in_words" == node.message.to_s || "distance_of_time_in_words_to_now" == node.message.to_s
|
25
22
|
add_error "not use time_ago_in_words"
|
26
23
|
end
|
@@ -23,20 +23,17 @@ module RailsBestPractices
|
|
23
23
|
# for rails3
|
24
24
|
#
|
25
25
|
# check all method_add_block nodes in route file.
|
26
|
-
# if the
|
26
|
+
# if the receiver of method_add_block node is with message resources,
|
27
27
|
# and in the block body of method_add_block node, there are more than @customize_count command nodes,
|
28
28
|
# whose message is get, post, update or delete,
|
29
29
|
# then these custom routes are overuse.
|
30
30
|
class OveruseRouteCustomizationsReview < Review
|
31
31
|
interesting_nodes :command_call, :method_add_block
|
32
32
|
interesting_files ROUTE_FILES
|
33
|
+
url "http://rails-bestpractices.com/posts/10-overuse-route-customizations"
|
33
34
|
|
34
35
|
VERBS = %w(get post update delete)
|
35
36
|
|
36
|
-
def url
|
37
|
-
"http://rails-bestpractices.com/posts/10-overuse-route-customizations"
|
38
|
-
end
|
39
|
-
|
40
37
|
def initialize(options = {})
|
41
38
|
super()
|
42
39
|
@customize_count = options['customize_count'] || 3
|
@@ -49,20 +46,20 @@ module RailsBestPractices
|
|
49
46
|
# and the second argument of call node is a hash,
|
50
47
|
# and the count of the pair (key/value) in hash is greater than @customize_count,
|
51
48
|
# then they are overuse route customizations.
|
52
|
-
|
49
|
+
add_callback :start_command_call do |node|
|
53
50
|
if member_and_collection_count_for_rails2(node) > @customize_count
|
54
|
-
add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.
|
51
|
+
add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.receiver.line
|
55
52
|
end
|
56
53
|
end
|
57
54
|
|
58
55
|
# check method_add_block node to see if the count of member and collection custom routes is more than @customize_count defined.
|
59
56
|
# this is for rails3 syntax.
|
60
57
|
#
|
61
|
-
# if the
|
58
|
+
# if the receiver of method_add_block node is with message "resources",
|
62
59
|
# and in the block body of method_add_block node, there are more than @customize_count call nodes,
|
63
60
|
# whose message is :get, :post, :update or :delete,
|
64
61
|
# then they are overuse route customizations.
|
65
|
-
|
62
|
+
add_callback :start_method_add_block do |node|
|
66
63
|
if member_and_collection_count_for_rails3(node) > @customize_count
|
67
64
|
add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.line
|
68
65
|
end
|
@@ -91,7 +88,7 @@ module RailsBestPractices
|
|
91
88
|
# check method_add_block node to calculate the count of member and collection custom routes.
|
92
89
|
# this is for rails3 syntax.
|
93
90
|
#
|
94
|
-
# if its
|
91
|
+
# if its receiver is with message "resources",
|
95
92
|
# then calculate the count of call nodes, whose message is get, post, update or delete,
|
96
93
|
# it is just the count of member and collection custom routes.
|
97
94
|
def member_and_collection_count_for_rails3(node)
|
@@ -14,17 +14,14 @@ module RailsBestPractices
|
|
14
14
|
class ProtectMassAssignmentReview < Review
|
15
15
|
interesting_nodes :class
|
16
16
|
interesting_files MODEL_FILES
|
17
|
-
|
18
|
-
def url
|
19
|
-
"http://rails-bestpractices.com/posts/148-protect-mass-assignment"
|
20
|
-
end
|
17
|
+
url "http://rails-bestpractices.com/posts/148-protect-mass-assignment"
|
21
18
|
|
22
19
|
# check class node, grep all command nodes,
|
23
20
|
# if config.active_record.whitelist_attributes is not set true,
|
24
21
|
# and if none of them is with message attr_accessible or attr_protected,
|
25
22
|
# and if not use devise or authlogic,
|
26
23
|
# then it should add attr_accessible or attr_protected to protect mass assignment.
|
27
|
-
|
24
|
+
add_callback :start_class do |node|
|
28
25
|
if !whitelist_attributes_config? && !rails_builtin?(node) && !devise?(node) &&
|
29
26
|
!authlogic?(node) && is_active_record?(node)
|
30
27
|
add_error "protect mass assignment"
|
@@ -14,13 +14,10 @@ module RailsBestPractices
|
|
14
14
|
class RemoveEmptyHelpersReview < Review
|
15
15
|
interesting_nodes :module
|
16
16
|
interesting_files HELPER_FILES
|
17
|
-
|
18
|
-
def url
|
19
|
-
"http://rails-bestpractices.com/posts/72-remove-empty-helpers"
|
20
|
-
end
|
17
|
+
url "http://rails-bestpractices.com/posts/72-remove-empty-helpers"
|
21
18
|
|
22
19
|
# check the body of module node, if it is nil, then it should be removed.
|
23
|
-
|
20
|
+
add_callback :start_module do |node|
|
24
21
|
if s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil) == node.body
|
25
22
|
add_error "remove empty helpers", node.file, node.line
|
26
23
|
end
|
@@ -15,7 +15,6 @@ module RailsBestPractices
|
|
15
15
|
class RemoveUnusedMethodsInControllersReview < Review
|
16
16
|
include Classable
|
17
17
|
include Moduleable
|
18
|
-
include Afterable
|
19
18
|
include Callable
|
20
19
|
include Exceptable
|
21
20
|
include InheritedResourcesable
|
@@ -33,7 +32,7 @@ module RailsBestPractices
|
|
33
32
|
end
|
34
33
|
|
35
34
|
# mark custom inherited_resources methods as used.
|
36
|
-
|
35
|
+
add_callback :end_class do |node|
|
37
36
|
if @inherited_resources
|
38
37
|
INHERITED_RESOURCES_METHODS.each do |method|
|
39
38
|
call_method(method)
|
@@ -47,7 +46,7 @@ module RailsBestPractices
|
|
47
46
|
end
|
48
47
|
|
49
48
|
# mark corresponding action as used for cells' render and render_call.
|
50
|
-
|
49
|
+
add_callback :start_command, :start_method_add_arg do |node|
|
51
50
|
case node.message.to_s
|
52
51
|
when "render_cell"
|
53
52
|
controller_name, action_name, _ = *node.arguments.all.map(&:to_s)
|
@@ -60,6 +59,11 @@ module RailsBestPractices
|
|
60
59
|
end
|
61
60
|
when "around_filter"
|
62
61
|
node.arguments.all.each { |argument| mark_used(argument) }
|
62
|
+
when "layout"
|
63
|
+
first_argument = node.arguments.all.first
|
64
|
+
if first_argument.sexp_type == :symbol_literal
|
65
|
+
mark_used(first_argument)
|
66
|
+
end
|
63
67
|
when "helper_method"
|
64
68
|
node.arguments.all.each { |argument| mark_publicize(argument.to_s) }
|
65
69
|
when "delegate"
|
@@ -73,10 +77,8 @@ module RailsBestPractices
|
|
73
77
|
end
|
74
78
|
end
|
75
79
|
|
76
|
-
alias :start_method_add_arg :start_command
|
77
|
-
|
78
80
|
# get all unused methods at the end of review process.
|
79
|
-
|
81
|
+
add_callback :after_check do
|
80
82
|
@routes.each do |route|
|
81
83
|
if "*" == route.action_name
|
82
84
|
action_names = @controller_methods.get_methods(route.controller_name_with_namespaces).map(&:method_name)
|
@@ -13,7 +13,6 @@ module RailsBestPractices
|
|
13
13
|
# then they are unused methods in helpers.
|
14
14
|
class RemoveUnusedMethodsInHelpersReview < Review
|
15
15
|
include Moduleable
|
16
|
-
include Afterable
|
17
16
|
include Callable
|
18
17
|
include Exceptable
|
19
18
|
|
@@ -26,7 +25,7 @@ module RailsBestPractices
|
|
26
25
|
end
|
27
26
|
|
28
27
|
# get all unused methods at the end of review process
|
29
|
-
|
28
|
+
add_callback :after_check do
|
30
29
|
@helper_methods.get_all_unused_methods.each do |method|
|
31
30
|
if !excepted?(method)
|
32
31
|
add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line
|
@@ -13,7 +13,6 @@ module RailsBestPractices
|
|
13
13
|
# if not, non called methods are unused.
|
14
14
|
class RemoveUnusedMethodsInModelsReview < Review
|
15
15
|
include Classable
|
16
|
-
include Afterable
|
17
16
|
include Callable
|
18
17
|
include Exceptable
|
19
18
|
|
@@ -32,7 +31,7 @@ module RailsBestPractices
|
|
32
31
|
|
33
32
|
# mark validate methods as used.
|
34
33
|
# mark key method and value method for collection_select and grouped_collection_select.
|
35
|
-
|
34
|
+
add_callback :start_command do |node|
|
36
35
|
arguments = node.arguments.all
|
37
36
|
case node.message.to_s
|
38
37
|
when "validate", "validate_on_create", "validate_on_update"
|
@@ -49,7 +48,7 @@ module RailsBestPractices
|
|
49
48
|
end
|
50
49
|
|
51
50
|
# mark key method and value method for collection_select and grouped_collection_select.
|
52
|
-
|
51
|
+
add_callback :start_command_call do |node|
|
53
52
|
arguments = node.arguments.all
|
54
53
|
case node.message.to_s
|
55
54
|
when "collection_select"
|
@@ -65,7 +64,7 @@ module RailsBestPractices
|
|
65
64
|
|
66
65
|
# mark key method and value method for options_from_collection_for_select and
|
67
66
|
# option_groups_from_collection_for_select.
|
68
|
-
|
67
|
+
add_callback :start_method_add_arg do |node|
|
69
68
|
arguments = node.arguments.all
|
70
69
|
case node.message.to_s
|
71
70
|
when "options_from_collection_for_select"
|
@@ -80,7 +79,7 @@ module RailsBestPractices
|
|
80
79
|
end
|
81
80
|
|
82
81
|
# get all unused methods at the end of review process.
|
83
|
-
|
82
|
+
add_callback :after_check do
|
84
83
|
@model_methods.get_all_unused_methods.each do |method|
|
85
84
|
if !excepted?(method) && method.method_name !~ /=$/
|
86
85
|
add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line
|
data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb
CHANGED
@@ -13,17 +13,14 @@ module RailsBestPractices
|
|
13
13
|
#
|
14
14
|
# Review process:
|
15
15
|
# check all method defines in the controller files,
|
16
|
-
# if there are multiple attribute assignments apply to one
|
17
|
-
# and the
|
16
|
+
# if there are multiple attribute assignments apply to one receiver,
|
17
|
+
# and the receiver is a variable,
|
18
18
|
# and after them there is a call node with message "save" or "save!",
|
19
19
|
# then these attribute assignments are complex creation, should be replaced with factory method.
|
20
20
|
class ReplaceComplexCreationWithFactoryMethodReview < Review
|
21
21
|
interesting_nodes :def
|
22
22
|
interesting_files CONTROLLER_FILES
|
23
|
-
|
24
|
-
def url
|
25
|
-
"http://rails-bestpractices.com/posts/6-replace-complex-creation-with-factory-method"
|
26
|
-
end
|
23
|
+
url "http://rails-bestpractices.com/posts/6-replace-complex-creation-with-factory-method"
|
27
24
|
|
28
25
|
def initialize(options = {})
|
29
26
|
super()
|
@@ -34,15 +31,15 @@ module RailsBestPractices
|
|
34
31
|
# @assigns_count, on one variable before save.
|
35
32
|
#
|
36
33
|
# it wll check every attrasgn nodes in method define node,
|
37
|
-
# if there are multiple assign nodes who have the same
|
38
|
-
# and the
|
34
|
+
# if there are multiple assign nodes who have the same receiver,
|
35
|
+
# and the receiver is a variable,
|
39
36
|
# and after them, there is a call node with message "save" or "save!",
|
40
37
|
# then these attribute assignments are complex creation, should be replaced with factory method.
|
41
|
-
|
38
|
+
add_callback :start_def do |node|
|
42
39
|
node.recursive_children do |child_node|
|
43
40
|
case child_node.sexp_type
|
44
41
|
when :assign
|
45
|
-
if :"." == child_node.
|
42
|
+
if :"." == child_node.receiver[2]
|
46
43
|
remember_variable_use_count(child_node)
|
47
44
|
end
|
48
45
|
when :call
|
@@ -55,11 +52,11 @@ module RailsBestPractices
|
|
55
52
|
|
56
53
|
private
|
57
54
|
# check the call node to see if it is with message "save" or "save!",
|
58
|
-
# and the count attribute assignment on the
|
55
|
+
# and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
|
59
56
|
# then it is a complex creation, should be replaced with factory method.
|
60
57
|
def check_variable_save(node)
|
61
58
|
if ["save", "save!"].include? node.message.to_s
|
62
|
-
variable = node.
|
59
|
+
variable = node.receiver.to_s
|
63
60
|
if variable_use_count[variable].to_i > @assigns_count
|
64
61
|
hint = "#{variable} attribute_assignment_count > #{@assigns_count}"
|
65
62
|
add_error "replace complex creation with factory method (#{hint})"
|
data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb
CHANGED
@@ -16,22 +16,11 @@ module RailsBestPractices
|
|
16
16
|
class ReplaceInstanceVariableWithLocalVariableReview < Review
|
17
17
|
interesting_nodes :var_ref, :vcall
|
18
18
|
interesting_files PARTIAL_VIEW_FILES
|
19
|
-
|
20
|
-
def url
|
21
|
-
"http://rails-bestpractices.com/posts/27-replace-instance-variable-with-local-variable"
|
22
|
-
end
|
23
|
-
|
24
|
-
# check ivar node in partial view file,
|
25
|
-
# it is an instance variable, and should be replaced with local variable.
|
26
|
-
def start_var_ref(node)
|
27
|
-
if node.to_s.start_with?('@')
|
28
|
-
add_error "replace instance variable with local variable"
|
29
|
-
end
|
30
|
-
end
|
19
|
+
url "http://rails-bestpractices.com/posts/27-replace-instance-variable-with-local-variable"
|
31
20
|
|
32
21
|
# check ivar node in partial view file,
|
33
22
|
# it is an instance variable, and should be replaced with local variable.
|
34
|
-
|
23
|
+
add_callback :start_var_ref, :start_vcall do |node|
|
35
24
|
if node.to_s.start_with?('@')
|
36
25
|
add_error "replace instance variable with local variable"
|
37
26
|
end
|