rails_best_practices 1.19.2 → 1.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.travis.yml +2 -3
  4. data/CHANGELOG.md +7 -7
  5. data/Gemfile +3 -5
  6. data/Gemfile.lock +125 -0
  7. data/Guardfile +2 -0
  8. data/README.md +6 -6
  9. data/Rakefile +2 -17
  10. data/assets/result.html.erb +2 -0
  11. data/lib/rails_best_practices.rb +3 -2
  12. data/lib/rails_best_practices/analyzer.rb +61 -49
  13. data/lib/rails_best_practices/cli.rb +22 -0
  14. data/lib/rails_best_practices/command.rb +1 -131
  15. data/lib/rails_best_practices/core/check.rb +64 -56
  16. data/lib/rails_best_practices/core/checks_loader.rb +24 -23
  17. data/lib/rails_best_practices/core/configs.rb +1 -2
  18. data/lib/rails_best_practices/core/controllers.rb +1 -2
  19. data/lib/rails_best_practices/core/error.rb +1 -1
  20. data/lib/rails_best_practices/core/helpers.rb +1 -2
  21. data/lib/rails_best_practices/core/mailers.rb +1 -2
  22. data/lib/rails_best_practices/core/methods.rb +27 -21
  23. data/lib/rails_best_practices/core/model_associations.rb +10 -5
  24. data/lib/rails_best_practices/core/models.rb +1 -2
  25. data/lib/rails_best_practices/core/modules.rb +1 -1
  26. data/lib/rails_best_practices/core/routes.rb +2 -2
  27. data/lib/rails_best_practices/core/runner.rb +67 -73
  28. data/lib/rails_best_practices/lexicals/long_line_check.rb +7 -3
  29. data/lib/rails_best_practices/option_parser.rb +156 -0
  30. data/lib/rails_best_practices/prepares.rb +1 -1
  31. data/lib/rails_best_practices/prepares/controller_prepare.rb +24 -17
  32. data/lib/rails_best_practices/prepares/gemfile_prepare.rb +2 -2
  33. data/lib/rails_best_practices/prepares/helper_prepare.rb +6 -1
  34. data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
  35. data/lib/rails_best_practices/prepares/mailer_prepare.rb +2 -1
  36. data/lib/rails_best_practices/prepares/model_prepare.rb +63 -23
  37. data/lib/rails_best_practices/prepares/route_prepare.rb +28 -21
  38. data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
  39. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +38 -34
  40. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +94 -89
  41. data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +15 -5
  42. data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +20 -8
  43. data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +1 -1
  44. data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +1 -1
  45. data/lib/rails_best_practices/reviews/hash_syntax_review.rb +16 -16
  46. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +12 -12
  47. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +10 -11
  48. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +25 -24
  49. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +4 -4
  50. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +9 -10
  51. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +10 -11
  52. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +24 -22
  53. data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +1 -1
  54. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +1 -2
  55. data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +1 -1
  56. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +8 -8
  57. data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +35 -32
  58. data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -4
  59. data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +26 -19
  60. data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +12 -10
  61. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +38 -18
  62. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +11 -11
  63. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +77 -74
  64. data/lib/rails_best_practices/reviews/review.rb +2 -1
  65. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -3
  66. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +12 -12
  67. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +18 -15
  68. data/lib/rails_best_practices/reviews/use_model_association_review.rb +15 -15
  69. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +24 -22
  70. data/lib/rails_best_practices/reviews/use_observer_review.rb +28 -28
  71. data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +6 -6
  72. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +68 -66
  73. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +9 -8
  74. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +16 -14
  75. data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +2 -1
  76. data/lib/rails_best_practices/version.rb +1 -1
  77. data/rails_best_practices.gemspec +38 -43
  78. data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +1 -2
  79. data/spec/rails_best_practices/analyzer_spec.rb +73 -42
  80. data/spec/rails_best_practices/core/check_spec.rb +5 -5
  81. data/spec/rails_best_practices/core/checks_loader_spec.rb +3 -3
  82. data/spec/rails_best_practices/core/configs_spec.rb +1 -1
  83. data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
  84. data/spec/rails_best_practices/core/error_spec.rb +21 -18
  85. data/spec/rails_best_practices/core/except_methods_spec.rb +7 -7
  86. data/spec/rails_best_practices/core/gems_spec.rb +4 -4
  87. data/spec/rails_best_practices/core/helpers_spec.rb +1 -1
  88. data/spec/rails_best_practices/core/klasses_spec.rb +3 -3
  89. data/spec/rails_best_practices/core/mailers_spec.rb +1 -1
  90. data/spec/rails_best_practices/core/methods_spec.rb +6 -6
  91. data/spec/rails_best_practices/core/model_associations_spec.rb +10 -6
  92. data/spec/rails_best_practices/core/model_attributes_spec.rb +4 -4
  93. data/spec/rails_best_practices/core/models_spec.rb +1 -1
  94. data/spec/rails_best_practices/core/modules_spec.rb +5 -5
  95. data/spec/rails_best_practices/core/routes_spec.rb +5 -5
  96. data/spec/rails_best_practices/core/runner_spec.rb +9 -7
  97. data/spec/rails_best_practices/core_ext/erubis_spec.rb +10 -10
  98. data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +32 -31
  99. data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
  100. data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
  101. data/spec/rails_best_practices/prepares/config_prepare_spec.rb +2 -2
  102. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +18 -10
  103. data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +17 -17
  104. data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +3 -3
  105. data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +3 -3
  106. data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
  107. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +79 -43
  108. data/spec/rails_best_practices/prepares/route_prepare_spec.rb +141 -76
  109. data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +2 -2
  110. data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +18 -12
  111. data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +28 -22
  112. data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +15 -13
  113. data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +31 -21
  114. data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
  115. data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +5 -5
  116. data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +13 -13
  117. data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +7 -7
  118. data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
  119. data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +29 -22
  120. data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
  121. data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +11 -6
  122. data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +32 -22
  123. data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
  124. data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +9 -7
  125. data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +9 -9
  126. data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +9 -9
  127. data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +5 -5
  128. data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +7 -7
  129. data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
  130. data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +24 -17
  131. data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +6 -6
  132. data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +64 -31
  133. data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +21 -14
  134. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +57 -53
  135. data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +10 -8
  136. data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +20 -14
  137. data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +54 -31
  138. data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +9 -9
  139. data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +13 -13
  140. data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +11 -9
  141. data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
  142. data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +35 -31
  143. data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
  144. data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +10 -8
  145. data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +31 -24
  146. data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +15 -11
  147. data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +14 -14
  148. data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +61 -59
  149. metadata +16 -18
@@ -20,27 +20,29 @@ module RailsBestPractices
20
20
  def initialize(options = {})
21
21
  super
22
22
  @helper_methods = Prepares.helper_methods
23
- self.class.interesting_files Prepares.helpers.map(&:descendants)
23
+ self.class.interesting_files *Prepares.helpers.map(&:descendants)
24
24
  end
25
25
 
26
26
  # get all unused methods at the end of review process
27
27
  add_callback :after_check do
28
28
  @helper_methods.get_all_unused_methods.each do |method|
29
- unless excepted?(method)
30
- add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line_number
31
- end
29
+ next if excepted?(method)
30
+
31
+ add_error "remove unused methods (#{method.class_name}##{method.method_name})",
32
+ method.file,
33
+ method.line_number
32
34
  end
33
35
  end
34
36
 
35
37
  protected
36
38
 
37
- def methods
38
- @helper_methods
39
- end
39
+ def methods
40
+ @helper_methods
41
+ end
40
42
 
41
- def internal_except_methods
42
- ['*#url_for']
43
- end
43
+ def internal_except_methods
44
+ ['*#url_for']
45
+ end
44
46
  end
45
47
  end
46
48
  end
@@ -80,30 +80,50 @@ module RailsBestPractices
80
80
  # get all unused methods at the end of review process.
81
81
  add_callback :after_check do
82
82
  @model_methods.get_all_unused_methods.each do |method|
83
- if !excepted?(method) && method.method_name !~ /=$/
84
- add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line_number
85
- end
83
+ next unless !excepted?(method) && method.method_name !~ /=$/
84
+
85
+ add_error "remove unused methods (#{method.class_name}##{method.method_name})",
86
+ method.file,
87
+ method.line_number
86
88
  end
87
89
  end
88
90
 
89
91
  protected
90
92
 
91
- def methods
92
- @model_methods
93
- end
93
+ def methods
94
+ @model_methods
95
+ end
94
96
 
95
- def internal_except_methods
96
- %w[
97
- initialize
98
- validate validate_each validate_on_create validate_on_update
99
- human_attribute_name assign_attributes attributes attribute
100
- to_xml to_json as_json to_param
101
- before_save before_create before_update before_destroy after_save after_create
102
- after_update after_destroy after_find after_initialize
103
- method_missing
104
- table_name module_prefix
105
- ].map { |method_name| "*\##{method_name}" }
106
- end
97
+ def internal_except_methods
98
+ %w[
99
+ initialize
100
+ validate
101
+ validate_each
102
+ validate_on_create
103
+ validate_on_update
104
+ human_attribute_name
105
+ assign_attributes
106
+ attributes
107
+ attribute
108
+ to_xml
109
+ to_json
110
+ as_json
111
+ to_param
112
+ before_save
113
+ before_create
114
+ before_update
115
+ before_destroy
116
+ after_save
117
+ after_create
118
+ after_update
119
+ after_destroy
120
+ after_find
121
+ after_initialize
122
+ method_missing
123
+ table_name
124
+ module_prefix
125
+ ].map { |method_name| "*\##{method_name}" }
126
+ end
107
127
  end
108
128
  end
109
129
  end
@@ -37,7 +37,7 @@ module RailsBestPractices
37
37
  node.recursive_children do |child_node|
38
38
  case child_node.sexp_type
39
39
  when :assign
40
- if :"." == child_node.receiver[2]
40
+ if child_node.receiver[2].to_s == '.'
41
41
  remember_variable_use_count(child_node)
42
42
  end
43
43
  when :call
@@ -49,18 +49,18 @@ module RailsBestPractices
49
49
 
50
50
  private
51
51
 
52
- # check the call node to see if it is with message "save" or "save!",
53
- # and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
54
- # then it is a complex creation, should be replaced with factory method.
55
- def check_variable_save(node)
56
- if ['save', 'save!'].include? node.message.to_s
57
- variable = node.receiver.to_s
58
- if variable_use_count[variable].to_i > @assigns_count
59
- hint = "#{variable} attribute_assignment_count > #{@assigns_count}"
60
- add_error "replace complex creation with factory method (#{hint})"
61
- end
52
+ # check the call node to see if it is with message "save" or "save!",
53
+ # and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
54
+ # then it is a complex creation, should be replaced with factory method.
55
+ def check_variable_save(node)
56
+ if ['save', 'save!'].include? node.message.to_s
57
+ variable = node.receiver.to_s
58
+ if variable_use_count[variable].to_i > @assigns_count
59
+ hint = "#{variable} attribute_assignment_count > #{@assigns_count}"
60
+ add_error "replace complex creation with factory method (#{hint})"
62
61
  end
63
62
  end
63
+ end
64
64
  end
65
65
  end
66
66
  end
@@ -38,23 +38,23 @@ module RailsBestPractices
38
38
 
39
39
  # check if the generated routes have the corresponding actions in controller for rails routes.
40
40
  add_callback :start_command, :start_command_call do |node|
41
- if 'resources' == node.message.to_s
41
+ if node.message.to_s == 'resources'
42
42
  if (mod = module_option(node))
43
43
  @namespaces << mod
44
44
  end
45
45
  check_resources(node)
46
46
  @resource_controllers << node.arguments.all.first.to_s
47
- elsif 'resource' == node.message.to_s
47
+ elsif node.message.to_s == 'resource'
48
48
  check_resource(node)
49
49
  @resource_controllers << node.arguments.all.first.to_s
50
50
  end
51
51
  end
52
52
 
53
53
  add_callback :end_command do |node|
54
- if 'resources' == node.message.to_s
54
+ if node.message.to_s == 'resources'
55
55
  @resource_controllers.pop
56
56
  @namespaces.pop if module_option(node)
57
- elsif 'resource' == node.message.to_s
57
+ elsif node.message.to_s == 'resource'
58
58
  @resource_controllers.pop
59
59
  end
60
60
  end
@@ -90,103 +90,106 @@ module RailsBestPractices
90
90
  end
91
91
 
92
92
  def check_method_add_block?(node)
93
- :command == node[1].sexp_type || (:command_call == node[1].sexp_type && 'map' != node.receiver.to_s)
93
+ node[1].sexp_type == :command || (node[1].sexp_type == :command_call && node.receiver.to_s != 'map')
94
94
  end
95
95
 
96
96
  private
97
97
 
98
- # check resources call, if the routes generated by resources does not exist in the controller.
99
- def check_resources(node)
100
- _check(node, resources_methods)
101
- end
98
+ # check resources call, if the routes generated by resources does not exist in the controller.
99
+ def check_resources(node)
100
+ _check(node, resources_methods)
101
+ end
102
102
 
103
- # check resource call, if the routes generated by resources does not exist in the controller.
104
- def check_resource(node)
105
- _check(node, resource_methods)
106
- end
103
+ # check resource call, if the routes generated by resources does not exist in the controller.
104
+ def check_resource(node)
105
+ _check(node, resource_methods)
106
+ end
107
107
 
108
- # get the controller name.
109
- def controller_name(node)
110
- if option_with_hash(node)
111
- option_node = node.arguments.all[1]
108
+ # get the controller name.
109
+ def controller_name(node)
110
+ if option_with_hash(node)
111
+ option_node = node.arguments.all[1]
112
+ name =
112
113
  if hash_key_exist?(option_node, 'controller')
113
- name = option_node.hash_value('controller').to_s
114
+ option_node.hash_value('controller').to_s
114
115
  else
115
- name = node.arguments.all.first.to_s.gsub('::', '').tableize
116
+ node.arguments.all.first.to_s.gsub('::', '').tableize
116
117
  end
117
- else
118
- name = node.arguments.all.first.to_s.gsub('::', '').tableize
119
- end
120
- namespaced_class_name(name)
118
+ else
119
+ name = node.arguments.all.first.to_s.gsub('::', '').tableize
121
120
  end
121
+ namespaced_class_name(name)
122
+ end
122
123
 
123
- # get the class name with namespace.
124
- def namespaced_class_name(name)
125
- class_name = "#{name.split('/').map(&:camelize).join('::')}Controller"
126
- if @namespaces.empty?
127
- class_name
128
- else
129
- @namespaces.map { |namespace| "#{namespace.camelize}::" }.join('') + class_name
130
- end
124
+ # get the class name with namespace.
125
+ def namespaced_class_name(name)
126
+ class_name = "#{name.split('/').map(&:camelize).join('::')}Controller"
127
+ if @namespaces.empty?
128
+ class_name
129
+ else
130
+ @namespaces.map { |namespace| "#{namespace.camelize}::" }.join('') + class_name
131
131
  end
132
+ end
132
133
 
133
- def _check(node, methods)
134
- controller_name = controller_name(node)
135
- return unless Prepares.controllers.include? controller_name
136
- _methods = _methods(node, methods)
137
- unless _methods.all? { |meth| Prepares.controller_methods.has_method?(controller_name, meth) }
138
- prepared_method_names = Prepares.controller_methods.get_methods(controller_name).map(&:method_name)
139
- only_methods = (_methods & prepared_method_names).map { |meth| ":#{meth}" }
140
- routes_message = if only_methods.size > 3
141
- "except: [#{(methods.map { |meth| ':' + meth } - only_methods).join(', ')}]"
142
- else
143
- "only: [#{only_methods.join(', ')}]"
144
- end
145
- add_error "restrict auto-generated routes #{friendly_route_name(node)} (#{routes_message})"
146
- end
134
+ def _check(node, methods)
135
+ controller_name = controller_name(node)
136
+ return unless Prepares.controllers.include? controller_name
137
+
138
+ _methods = _methods(node, methods)
139
+ unless _methods.all? { |meth| Prepares.controller_methods.has_method?(controller_name, meth) }
140
+ prepared_method_names = Prepares.controller_methods.get_methods(controller_name).map(&:method_name)
141
+ only_methods = (_methods & prepared_method_names).map { |meth| ":#{meth}" }
142
+ routes_message =
143
+ if only_methods.size > 3
144
+ "except: [#{(methods.map { |meth| ':' + meth } - only_methods).join(', ')}]"
145
+ else
146
+ "only: [#{only_methods.join(', ')}]"
147
+ end
148
+ add_error "restrict auto-generated routes #{friendly_route_name(node)} (#{routes_message})"
147
149
  end
150
+ end
148
151
 
149
- def _methods(node, methods)
150
- if option_with_hash(node)
151
- option_node = node.arguments.all[1]
152
- if hash_key_exist?(option_node, 'only')
153
- option_node.hash_value('only').to_s == 'none' ? [] : Array(option_node.hash_value('only').to_object)
154
- elsif hash_key_exist?(option_node, 'except')
155
- if option_node.hash_value('except').to_s == 'all'
156
- []
157
- else
158
- (methods - Array(option_node.hash_value('except').to_object))
159
- end
152
+ def _methods(node, methods)
153
+ if option_with_hash(node)
154
+ option_node = node.arguments.all[1]
155
+ if hash_key_exist?(option_node, 'only')
156
+ option_node.hash_value('only').to_s == 'none' ? [] : Array(option_node.hash_value('only').to_object)
157
+ elsif hash_key_exist?(option_node, 'except')
158
+ if option_node.hash_value('except').to_s == 'all'
159
+ []
160
160
  else
161
- methods
161
+ (methods - Array(option_node.hash_value('except').to_object))
162
162
  end
163
163
  else
164
164
  methods
165
165
  end
166
+ else
167
+ methods
166
168
  end
169
+ end
167
170
 
168
- def module_option(node)
169
- option_node = node.arguments[1].last
170
- if option_node && option_node.sexp_type == :bare_assoc_hash && hash_key_exist?(option_node, 'module')
171
- option_node.hash_value('module').to_s
172
- end
171
+ def module_option(node)
172
+ option_node = node.arguments[1].last
173
+ if option_node && option_node.sexp_type == :bare_assoc_hash && hash_key_exist?(option_node, 'module')
174
+ option_node.hash_value('module').to_s
173
175
  end
176
+ end
174
177
 
175
- def option_with_hash(node)
176
- node.arguments.all.size > 1 && :bare_assoc_hash == node.arguments.all[1].sexp_type
177
- end
178
+ def option_with_hash(node)
179
+ node.arguments.all.size > 1 && node.arguments.all[1].sexp_type == :bare_assoc_hash
180
+ end
178
181
 
179
- def hash_key_exist?(node, key)
180
- node.hash_keys && node.hash_keys.include?(key)
181
- end
182
+ def hash_key_exist?(node, key)
183
+ node.hash_keys&.include?(key)
184
+ end
182
185
 
183
- def friendly_route_name(node)
184
- if @resource_controllers.last == node.arguments.to_s
185
- [@namespaces.join('/'), @resource_controllers.join('/')].delete_if(&:blank?).join('/')
186
- else
187
- [@namespaces.join('/'), @resource_controllers.join('/'), node.arguments.to_s].delete_if(&:blank?).join('/')
188
- end
186
+ def friendly_route_name(node)
187
+ if @resource_controllers.last == node.arguments.to_s
188
+ [@namespaces.join('/'), @resource_controllers.join('/')].delete_if(&:blank?).join('/')
189
+ else
190
+ [@namespaces.join('/'), @resource_controllers.join('/'), node.arguments.to_s].delete_if(&:blank?).join('/')
189
191
  end
192
+ end
190
193
  end
191
194
  end
192
195
  end
@@ -13,7 +13,7 @@ module RailsBestPractices
13
13
  # then save it to as key in @variable_use_count hash, and add the call count (hash value).
14
14
  def remember_variable_use_count(node)
15
15
  variable_node = variable(node)
16
- if variable_node && 'self' != variable_node.to_s && @last_variable_node != variable_node
16
+ if variable_node && variable_node.to_s != 'self' && @last_variable_node != variable_node
17
17
  @last_variable_node = variable_node
18
18
  variable_use_count[variable_node.to_s] ||= 0
19
19
  variable_use_count[variable_node.to_s] += 1
@@ -36,6 +36,7 @@ module RailsBestPractices
36
36
  node = node.receiver
37
37
  end
38
38
  return if %i[fcall hash].include?(node.receiver.sexp_type)
39
+
39
40
  node.receiver
40
41
  end
41
42
 
@@ -21,10 +21,9 @@ module RailsBestPractices
21
21
  # if its message is render and the arguments contain a key action, template or file,
22
22
  # then it should be replaced by simplified syntax.
23
23
  add_callback :start_command do |node|
24
- if 'render' == node.message.to_s
24
+ if node.message.to_s == 'render'
25
25
  keys = node.arguments.all.first.hash_keys
26
- if keys && keys.size == 1 &&
27
- (keys.include?('action') || keys.include?('template') || keys.include?('file'))
26
+ if keys && keys.size == 1 && (keys.include?('action') || keys.include?('template') || keys.include?('file'))
28
27
  add_error 'simplify render in controllers'
29
28
  end
30
29
  end
@@ -22,10 +22,10 @@ module RailsBestPractices
22
22
  # if its message is render and the arguments contain a key partial,
23
23
  # then it should be replaced by simplified syntax.
24
24
  add_callback :start_command do |node|
25
- if 'render' == node.message.to_s
26
- hash_node = node.arguments.all.first
27
- if hash_node && :bare_assoc_hash == hash_node.sexp_type &&
28
- include_partial?(hash_node) && valid_hash?(hash_node)
25
+ if node.message.to_s == 'render'
26
+ hash_node = node.arguments.all.first
27
+ if hash_node && hash_node.sexp_type == :bare_assoc_hash && include_partial?(hash_node) &&
28
+ valid_hash?(hash_node)
29
29
  add_error 'simplify render in views'
30
30
  end
31
31
  end
@@ -33,15 +33,15 @@ module RailsBestPractices
33
33
 
34
34
  protected
35
35
 
36
- def include_partial?(hash_node)
37
- hash_node.hash_keys.include?('partial') && !hash_node.hash_value('partial').to_s.include?('/')
38
- end
36
+ def include_partial?(hash_node)
37
+ hash_node.hash_keys.include?('partial') && !hash_node.hash_value('partial').to_s.include?('/')
38
+ end
39
39
 
40
- def valid_hash?(hash_node)
41
- keys = hash_node.hash_keys
42
- keys.delete('partial')
43
- (keys - VALID_KEYS).empty?
44
- end
40
+ def valid_hash?(hash_node)
41
+ keys = hash_node.hash_keys
42
+ keys.delete('partial')
43
+ (keys - VALID_KEYS).empty?
44
+ end
45
45
  end
46
46
  end
47
47
  end
@@ -12,6 +12,7 @@ module RailsBestPractices
12
12
  # Review process:
13
13
  # check all first code line_number in method definitions (actions),
14
14
  # if they are duplicated, then they should be moved to before_filter.
15
+
15
16
  class UseBeforeFilterReview < Review
16
17
  interesting_nodes :class
17
18
  interesting_files CONTROLLER_FILES
@@ -34,29 +35,31 @@ module RailsBestPractices
34
35
  var_ref_or_vcall_included = %i[var_ref vcall].include?(statement_node.sexp_type)
35
36
  private_or_protected_included = %w[protected private].include?(statement_node.to_s)
36
37
  break if var_ref_or_vcall_included && private_or_protected_included
37
- remember_first_sentence(statement_node) if :def == statement_node.sexp_type
38
+
39
+ remember_first_sentence(statement_node) if statement_node.sexp_type == :def
38
40
  end
39
41
  @first_sentences.each do |_first_sentence, def_nodes|
40
- if def_nodes.size > @customize_count
41
- add_error "use before_filter for #{def_nodes.map { |node| node.method_name.to_s }.join(',')}",
42
- node.file,
43
- def_nodes.map(&:line_number).join(',')
44
- end
42
+ next unless def_nodes.size > @customize_count
43
+
44
+ add_error "use before_filter for #{def_nodes.map { |node| node.method_name.to_s }.join(',')}",
45
+ node.file,
46
+ def_nodes.map(&:line_number).join(',')
45
47
  end
46
48
  end
47
49
 
48
50
  private
49
51
 
50
- # check method define node, and remember the first sentence.
51
- def remember_first_sentence(node)
52
- first_sentence = node.body.statements.first
53
- return unless first_sentence
54
- first_sentence = first_sentence.remove_line_and_column
55
- unless first_sentence == s(:nil)
56
- @first_sentences[first_sentence] ||= []
57
- @first_sentences[first_sentence] << node
58
- end
52
+ # check method define node, and remember the first sentence.
53
+ def remember_first_sentence(node)
54
+ first_sentence = node.body.statements.first
55
+ return unless first_sentence
56
+
57
+ first_sentence = first_sentence.remove_line_and_column
58
+ unless first_sentence == s(:nil)
59
+ @first_sentences[first_sentence] ||= []
60
+ @first_sentences[first_sentence] << node
59
61
  end
62
+ end
60
63
  end
61
64
  end
62
65
  end