rails_best_practices 1.10.1 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|