rails_best_practices 1.19.2 → 1.20.1

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