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.
Files changed (76) hide show
  1. data/.gitignore +1 -0
  2. data/README.md +11 -6
  3. data/assets/result.html.erb +76 -46
  4. data/install_supported_rubies.sh +3 -0
  5. data/lib/rails_best_practices.rb +2 -1
  6. data/lib/rails_best_practices/analyzer.rb +10 -8
  7. data/lib/rails_best_practices/core.rb +0 -4
  8. data/lib/rails_best_practices/core/check.rb +41 -117
  9. data/lib/rails_best_practices/core/error.rb +3 -9
  10. data/lib/rails_best_practices/core/runner.rb +20 -80
  11. data/lib/rails_best_practices/lexicals/long_line_check.rb +2 -1
  12. data/lib/rails_best_practices/lexicals/remove_tab_check.rb +1 -3
  13. data/lib/rails_best_practices/lexicals/remove_trailing_whitespace_check.rb +1 -3
  14. data/lib/rails_best_practices/prepares/config_prepare.rb +1 -1
  15. data/lib/rails_best_practices/prepares/controller_prepare.rb +7 -8
  16. data/lib/rails_best_practices/prepares/helper_prepare.rb +2 -2
  17. data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
  18. data/lib/rails_best_practices/prepares/model_prepare.rb +6 -7
  19. data/lib/rails_best_practices/prepares/route_prepare.rb +12 -13
  20. data/lib/rails_best_practices/prepares/schema_prepare.rb +2 -2
  21. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +19 -15
  22. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +10 -17
  23. data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +2 -5
  24. data/lib/rails_best_practices/reviews/hash_syntax_review.rb +3 -30
  25. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +7 -10
  26. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +5 -9
  27. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +10 -13
  28. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +6 -9
  29. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +2 -5
  30. data/lib/rails_best_practices/reviews/move_code_into_model_review.rb +7 -13
  31. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +3 -6
  32. data/lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb +6 -9
  33. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +3 -6
  34. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +4 -7
  35. data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +2 -5
  36. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +7 -10
  37. data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +2 -5
  38. data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +2 -5
  39. data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +8 -6
  40. data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +1 -2
  41. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +4 -5
  42. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +9 -12
  43. data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb +2 -13
  44. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +18 -26
  45. data/lib/rails_best_practices/reviews/review.rb +6 -7
  46. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -5
  47. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +2 -5
  48. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +2 -5
  49. data/lib/rails_best_practices/reviews/use_model_association_review.rb +11 -14
  50. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +11 -8
  51. data/lib/rails_best_practices/reviews/use_observer_review.rb +8 -11
  52. data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +1 -1
  53. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +12 -18
  54. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +7 -10
  55. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +4 -10
  56. data/lib/rails_best_practices/version.rb +1 -1
  57. data/rails_best_practices.gemspec +1 -1
  58. data/rails_best_practices.yml +5 -5
  59. data/spec/rails_best_practices/core/check_spec.rb +0 -67
  60. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +0 -1
  61. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +0 -4
  62. data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +3 -30
  63. data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +22 -0
  64. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +19 -0
  65. data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +2 -2
  66. data/spec/spec_helper.rb +0 -4
  67. metadata +28 -41
  68. data/Gemfile.lock +0 -71
  69. data/lib/rails_best_practices/core/checking_visitor.rb +0 -80
  70. data/lib/rails_best_practices/core/nil.rb +0 -37
  71. data/lib/rails_best_practices/core_ext/enumerable.rb +0 -9
  72. data/lib/rails_best_practices/core_ext/sexp.rb +0 -840
  73. data/spec/rails_best_practices/core/checking_visitor_spec.rb +0 -79
  74. data/spec/rails_best_practices/core/nil_spec.rb +0 -37
  75. data/spec/rails_best_practices/core_ext/enumerable_spec.rb +0 -7
  76. 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 subject,
14
- # and the subject is a variable, then they should be moved into model.
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 subject who is a variable.
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 subject,
33
- # and the subject is a variable, then the conditional statement nodes should be moved into model.
34
- def start_if(node)
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
- def start_method_add_arg(node)
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 subject of method_add_arg node is a constant,
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 subject,
15
- # and the subject is a variable,
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 subject,
34
- # and the subject is a variable,
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
- def start_def(node)
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
- def start_method_add_block(node)
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 subject of the method_add_block is with message "resources" or "resource",
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
- def start_command_call(node)
31
- if "map" == node.subject.to_s && "connect" == node.message.to_s &&
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
- def start_command(node)
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
- def start_fcall(node)
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 subject of method_add_block node is with message resources,
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
- def start_command_call(node)
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.subject.line
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 subject of method_add_block node is with message "resources",
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
- def start_method_add_block(node)
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 subject is with message "resources",
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
- def start_class(node)
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
- def start_module(node)
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
- def end_class(node)
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
- def start_command(node)
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
- def after_review
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
- def after_review
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
- def start_command(node)
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
- def start_command_call(node)
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
- def start_method_add_arg(node)
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
- def after_review
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
@@ -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 subject,
17
- # and the subject is a variable,
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 subject,
38
- # and the subject is a variable,
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
- def start_def(node)
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.subject[2]
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 subject of the call node is greater than @assign_count defined,
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.subject.to_s
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})"
@@ -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
- def start_vcall(node)
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