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.
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