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
@@ -4,7 +4,7 @@ require_rel 'prepares'
4
4
 
5
5
  module RailsBestPractices
6
6
  module Prepares
7
- class <<self
7
+ class << self
8
8
  def klasses
9
9
  models + mailers + controllers
10
10
  end
@@ -3,6 +3,7 @@
3
3
  module RailsBestPractices
4
4
  module Prepares
5
5
  # Remember controllers and controller methods
6
+
6
7
  class ControllerPrepare < Core::Check
7
8
  include Core::Check::Classable
8
9
  include Core::Check::InheritedResourcesable
@@ -24,43 +25,42 @@ module RailsBestPractices
24
25
  # also check if the controller is inherit from InheritedResources::Base.
25
26
  add_callback :start_class do |_node|
26
27
  @controllers << @klass
27
- if @inherited_resources
28
- @actions = DEFAULT_ACTIONS
29
- end
28
+ @current_controller_name = @klass.to_s
29
+ @actions = DEFAULT_ACTIONS if @inherited_resources
30
30
  end
31
31
 
32
32
  # remember the action names at the end of class node if the controller is a InheritedResources.
33
33
  add_callback :end_class do |node|
34
- if @inherited_resources && 'ApplicationController' != current_class_name
34
+ if @inherited_resources && @current_controller_name != 'ApplicationController'
35
35
  @actions.each do |action|
36
- @methods.add_method(current_class_name, action, 'file' => node.file, 'line_number' => node.line_number)
36
+ @methods.add_method(
37
+ @current_controller_name,
38
+ action,
39
+ 'file' => node.file, 'line_number' => node.line_number
40
+ )
37
41
  end
38
42
  end
39
43
  end
40
44
 
41
45
  # check if there is a DSL call inherit_resources.
42
46
  add_callback :start_var_ref do |_node|
43
- if @inherited_resources
44
- @actions = DEFAULT_ACTIONS
45
- end
47
+ @actions = DEFAULT_ACTIONS if @inherited_resources
46
48
  end
47
49
 
48
50
  # check if there is a DSL call inherit_resources.
49
51
  add_callback :start_vcall do |_node|
50
- if @inherited_resources
51
- @actions = DEFAULT_ACTIONS
52
- end
52
+ @actions = DEFAULT_ACTIONS if @inherited_resources
53
53
  end
54
54
 
55
55
  # restrict actions for inherited_resources
56
56
  add_callback :start_command do |node|
57
- if 'include' == node.message.to_s
57
+ if node.message.to_s == 'include'
58
58
  @helpers.add_module_descendant(node.arguments.all.first.to_s, current_class_name)
59
- elsif @inherited_resources && 'actions' == node.message.to_s
60
- if 'all' == node.arguments.all.first.to_s
59
+ elsif @inherited_resources && node.message.to_s == 'actions'
60
+ if node.arguments.all.first.to_s == 'all'
61
61
  @actions = DEFAULT_ACTIONS
62
62
  option_argument = node.arguments.all[1]
63
- if option_argument && :bare_assoc_hash == option_argument.sexp_type && option_argument.hash_value('except')
63
+ if option_argument && option_argument.sexp_type == :bare_assoc_hash && option_argument.hash_value('except')
64
64
  @actions -= option_argument.hash_value('except').to_object
65
65
  end
66
66
  else
@@ -83,14 +83,21 @@ module RailsBestPractices
83
83
  # }
84
84
  add_callback :start_def do |node|
85
85
  method_name = node.method_name.to_s
86
- @methods.add_method(current_class_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
86
+ @methods.add_method(
87
+ current_class_name,
88
+ method_name,
89
+ { 'file' => node.file, 'line_number' => node.line_number },
90
+ current_access_control
91
+ )
87
92
  end
88
93
 
89
94
  # ask Reviews::RemoveUnusedMoethodsInHelperReview to check the controllers who include helpers.
90
95
  add_callback :after_check do
91
96
  descendants = @helpers.map(&:descendants).flatten
92
97
  if descendants.present?
93
- Reviews::RemoveUnusedMethodsInHelpersReview.interesting_files *descendants.map { |descendant| /#{descendant.underscore}/ }
98
+ Reviews::RemoveUnusedMethodsInHelpersReview.interesting_files *descendants.map { |descendant|
99
+ /#{descendant.underscore}/
100
+ }
94
101
  end
95
102
  end
96
103
  end
@@ -10,10 +10,10 @@ module RailsBestPractices
10
10
  @gems = Prepares.gems
11
11
  end
12
12
 
13
- def check(filename, content)
13
+ def check(_filename, content)
14
14
  content.split("\n").each do |line|
15
15
  if line =~ /([^ ]+) \((\d.*)\)/
16
- @gems << Core::Gem.new($1, $2)
16
+ @gems << Core::Gem.new(Regexp.last_match(1), Regexp.last_match(2))
17
17
  end
18
18
  end
19
19
  end
@@ -32,7 +32,12 @@ module RailsBestPractices
32
32
  add_callback :start_def do |node|
33
33
  if node.file =~ HELPER_FILES
34
34
  method_name = node.method_name.to_s
35
- @methods.add_method(current_module_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
35
+ @methods.add_method(
36
+ current_module_name,
37
+ method_name,
38
+ { 'file' => node.file, 'line_number' => node.line_number },
39
+ current_access_control
40
+ )
36
41
  end
37
42
  end
38
43
  end
@@ -3,6 +3,7 @@
3
3
  module RailsBestPractices
4
4
  module Prepares
5
5
  # Check all initializers
6
+
6
7
  class InitializerPrepare < Core::Check
7
8
  interesting_nodes :method_add_arg, :class
8
9
  interesting_files INITIALIZER_FILES
@@ -21,9 +22,8 @@ module RailsBestPractices
21
22
  # check if the node is
22
23
  # ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
23
24
  def include_forbidden_attributes_protection?(node)
24
- 'ActiveRecord::Base' == node.receiver.to_s &&
25
- 'send' == node.message.to_s &&
26
- ['include', 'ActiveModel::ForbiddenAttributesProtection'] == node.arguments.all.map(&:to_s)
25
+ node.receiver.to_s == 'ActiveRecord::Base' && node.message.to_s == 'send' &&
26
+ node.arguments.all.map(&:to_s) == ['include', 'ActiveModel::ForbiddenAttributesProtection']
27
27
  end
28
28
  end
29
29
  end
@@ -3,6 +3,7 @@
3
3
  module RailsBestPractices
4
4
  module Prepares
5
5
  # Remember the mailer names.
6
+
6
7
  class MailerPrepare < Core::Check
7
8
  include Core::Check::Classable
8
9
 
@@ -18,7 +19,7 @@ module RailsBestPractices
18
19
  # if it is a subclass of ActionMailer::Base,
19
20
  # then remember its class name.
20
21
  add_callback :start_class do |_node|
21
- if 'ActionMailer::Base' == current_extend_class_name
22
+ if current_extend_class_name == 'ActionMailer::Base'
22
23
  @mailers << @klass
23
24
  end
24
25
  end
@@ -3,6 +3,7 @@
3
3
  module RailsBestPractices
4
4
  module Prepares
5
5
  # Remember models and model associations.
6
+
6
7
  class ModelPrepare < Core::Check
7
8
  include Core::Check::Classable
8
9
  include Core::Check::Accessable
@@ -10,7 +11,17 @@ module RailsBestPractices
10
11
  interesting_nodes :class, :def, :defs, :command, :alias
11
12
  interesting_files MODEL_FILES
12
13
 
13
- ASSOCIATION_METHODS = %w[belongs_to has_one has_many has_and_belongs_to_many embeds_many embeds_one embedded_in many one].freeze
14
+ ASSOCIATION_METHODS = %w[
15
+ belongs_to
16
+ has_one
17
+ has_many
18
+ has_and_belongs_to_many
19
+ embeds_many
20
+ embeds_one
21
+ embedded_in
22
+ many
23
+ one
24
+ ].freeze
14
25
 
15
26
  def initialize
16
27
  @models = Prepares.models
@@ -21,7 +32,7 @@ module RailsBestPractices
21
32
 
22
33
  # remember the class name.
23
34
  add_callback :start_class do |_node|
24
- if 'ActionMailer::Base' != current_extend_class_name
35
+ if current_extend_class_name != 'ActionMailer::Base'
25
36
  @models << @klass
26
37
  end
27
38
  end
@@ -39,11 +50,14 @@ module RailsBestPractices
39
50
  # }
40
51
  # }
41
52
  add_callback :start_def do |node|
42
- if @klass &&
43
- 'ActionMailer::Base' != current_extend_class_name &&
44
- (classable_modules.empty? || klasses.any?)
53
+ if @klass && current_extend_class_name != 'ActionMailer::Base' && (classable_modules.empty? || klasses.any?)
45
54
  method_name = node.method_name.to_s
46
- @methods.add_method(current_class_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
55
+ @methods.add_method(
56
+ current_class_name,
57
+ method_name,
58
+ { 'file' => node.file, 'line_number' => node.line_number },
59
+ current_access_control
60
+ )
47
61
  end
48
62
  end
49
63
 
@@ -60,9 +74,14 @@ module RailsBestPractices
60
74
  # }
61
75
  # }
62
76
  add_callback :start_defs do |node|
63
- if @klass && 'ActionMailer::Base' != current_extend_class_name
77
+ if @klass && current_extend_class_name != 'ActionMailer::Base'
64
78
  method_name = node.method_name.to_s
65
- @methods.add_method(current_class_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
79
+ @methods.add_method(
80
+ current_class_name,
81
+ method_name,
82
+ { 'file' => node.file, 'line_number' => node.line_number },
83
+ current_access_control
84
+ )
66
85
  end
67
86
  end
68
87
 
@@ -81,15 +100,31 @@ module RailsBestPractices
81
100
  case node.message.to_s
82
101
  when 'named_scope', 'scope', 'alias_method'
83
102
  method_name = node.arguments.all.first.to_s
84
- @methods.add_method(current_class_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
103
+ @methods.add_method(
104
+ current_class_name,
105
+ method_name,
106
+ { 'file' => node.file, 'line_number' => node.line_number },
107
+ current_access_control
108
+ )
85
109
  when 'alias_method_chain'
86
110
  method, feature = *node.arguments.all.map(&:to_s)
87
- @methods.add_method(current_class_name, "#{method}_with_#{feature}", { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
88
- @methods.add_method(current_class_name, method.to_s, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
111
+ @methods.add_method(
112
+ current_class_name,
113
+ "#{method}_with_#{feature}",
114
+ { 'file' => node.file, 'line_number' => node.line_number },
115
+ current_access_control
116
+ )
117
+ @methods.add_method(
118
+ current_class_name,
119
+ method.to_s,
120
+ { 'file' => node.file, 'line_number' => node.line_number },
121
+ current_access_control
122
+ )
89
123
  when 'field'
90
124
  arguments = node.arguments.all
91
125
  attribute_name = arguments.first.to_s
92
- attribute_type = arguments.last.hash_value('type').present? ? arguments.last.hash_value('type').to_s : 'String'
126
+ attribute_type =
127
+ arguments.last.hash_value('type').present? ? arguments.last.hash_value('type').to_s : 'String'
93
128
  @model_attributes.add_attribute(current_class_name, attribute_name, attribute_type)
94
129
  when 'key'
95
130
  attribute_name, attribute_type = node.arguments.all.map(&:to_s)
@@ -102,7 +137,12 @@ module RailsBestPractices
102
137
  # check alias node to remembr the alias methods.
103
138
  add_callback :start_alias do |node|
104
139
  method_name = node.new_method.to_s
105
- @methods.add_method(current_class_name, method_name, { 'file' => node.file, 'line_number' => node.line_number }, current_access_control)
140
+ @methods.add_method(
141
+ current_class_name,
142
+ method_name,
143
+ { 'file' => node.file, 'line_number' => node.line_number },
144
+ current_access_control
145
+ )
106
146
  end
107
147
 
108
148
  # after prepare process, fix incorrect associations' class_name.
@@ -122,17 +162,17 @@ module RailsBestPractices
122
162
 
123
163
  private
124
164
 
125
- # remember associations, with class to association names.
126
- def remember_association(node)
127
- association_meta = node.message.to_s
128
- association_name = node.arguments.all.first.to_s
129
- arguments_node = node.arguments.all.last
130
- if arguments_node.hash_value('class_name').present?
131
- association_class = arguments_node.hash_value('class_name').to_s
132
- end
133
- association_class ||= association_name.classify
134
- @model_associations.add_association(current_class_name, association_name, association_meta, association_class)
165
+ # remember associations, with class to association names.
166
+ def remember_association(node)
167
+ association_meta = node.message.to_s
168
+ association_name = node.arguments.all.first.to_s
169
+ arguments_node = node.arguments.all.last
170
+ if arguments_node.hash_value('class_name').present?
171
+ association_class = arguments_node.hash_value('class_name').to_s
135
172
  end
173
+ association_class ||= association_name.classify
174
+ @model_associations.add_association(current_class_name, association_name, association_meta, association_class)
175
+ end
136
176
  end
137
177
  end
138
178
  end
@@ -27,21 +27,20 @@ module RailsBestPractices
27
27
  first_argument = node.arguments.all.first
28
28
  second_argument = node.arguments.all[1]
29
29
  if @controller_names.last
30
- if :bare_assoc_hash == first_argument.sexp_type
30
+ if first_argument.sexp_type == :bare_assoc_hash
31
31
  action_names = [first_argument.hash_values.first.to_s]
32
- elsif :array == first_argument.sexp_type
32
+ elsif first_argument.sexp_type == :array
33
33
  action_names = first_argument.array_values.map(&:to_s)
34
- elsif :bare_assoc_hash == second_argument.try(:sexp_type) && second_argument.hash_value('to').present?
35
- if :string_literal == second_argument.hash_value('to').sexp_type
34
+ elsif second_argument.try(:sexp_type) == :bare_assoc_hash && second_argument.hash_value('to').present?
35
+ if second_argument.hash_value('to').sexp_type == :string_literal
36
36
  controller_name, action_name = second_argument.hash_value('to').to_s.split('#')
37
37
  action_names = [action_name]
38
38
  else
39
39
  action_names = [second_argument.hash_value('to').to_s]
40
40
  end
41
- elsif :symbol_literal == first_argument.sexp_type && second_argument.try(:sexp_type) && \
42
- :symbol_literal == second_argument.sexp_type
43
- action_names = node.arguments.all.select \
44
- { |arg| :symbol_literal == arg.sexp_type }.map(&:to_s)
41
+ elsif first_argument.sexp_type == :symbol_literal && second_argument.try(:sexp_type) &&
42
+ second_argument.sexp_type == :symbol_literal
43
+ action_names = node.arguments.all.select { |arg| arg.sexp_type == :symbol_literal }.map(&:to_s)
45
44
  else
46
45
  action_names = [first_argument.to_s]
47
46
  end
@@ -49,18 +48,18 @@ module RailsBestPractices
49
48
  @routes.add_route(current_namespaces, current_controller_name, action_name)
50
49
  end
51
50
  else
52
- if :bare_assoc_hash == first_argument.sexp_type
51
+ if first_argument.sexp_type == :bare_assoc_hash
53
52
  route_node = first_argument.hash_values.first
54
53
  # do not parse redirect block
55
- if :method_add_arg != route_node.sexp_type
54
+ if route_node.sexp_type != :method_add_arg
56
55
  controller_name, action_name = route_node.to_s.split('#')
57
56
  @routes.add_route(current_namespaces, controller_name.underscore, action_name)
58
57
  end
59
- elsif :array == first_argument.sexp_type
58
+ elsif first_argument.sexp_type == :array
60
59
  first_argument.array_values.map(&:to_s).each do |action_node|
61
60
  @routes.add_route(current_namespaces, controller_name, action_node.to_s)
62
61
  end
63
- elsif :bare_assoc_hash == second_argument.try(:sexp_type)
62
+ elsif second_argument.try(:sexp_type) == :bare_assoc_hash
64
63
  if second_argument.hash_value('to').present?
65
64
  controller_name, action_name = second_argument.hash_value('to').to_s.split('#')
66
65
  else
@@ -78,12 +77,16 @@ module RailsBestPractices
78
77
  case options.sexp_type
79
78
  when :bare_assoc_hash
80
79
  if options.hash_value('controller').present?
81
- return if :regexp_literal == options.hash_value('controller').sexp_type
80
+ return if options.hash_value('controller').sexp_type == :regexp_literal
81
+
82
82
  controller_name = options.hash_value('controller').to_s
83
83
  action_name = options.hash_value('action').present? ? options.hash_value('action').to_s : '*'
84
84
  @routes.add_route(current_namespaces, controller_name, action_name)
85
85
  else
86
- route_node = options.hash_values.find { |value_node| :string_literal == value_node.sexp_type && value_node.to_s.include?('#') }
86
+ route_node =
87
+ options.hash_values.find do |value_node|
88
+ value_node.sexp_type == :string_literal && value_node.to_s.include?('#')
89
+ end
87
90
  if route_node.present?
88
91
  controller_name, action_name = route_node.to_s.split('#')
89
92
  @routes.add_route(current_namespaces, controller_name.underscore, action_name)
@@ -100,7 +103,10 @@ module RailsBestPractices
100
103
  options = node.arguments.all.last
101
104
  case options.sexp_type
102
105
  when :bare_assoc_hash
103
- route_node = options.hash_values.find { |value_node| :string_literal == value_node.sexp_type && value_node.to_s.include?('#') }
106
+ route_node =
107
+ options.hash_values.find do |value_node|
108
+ value_node.sexp_type == :string_literal && value_node.to_s.include?('#')
109
+ end
104
110
  if route_node.present?
105
111
  controller_name, action_name = route_node.to_s.split('#')
106
112
  @routes.add_route(current_namespaces, controller_name.underscore, action_name)
@@ -144,14 +150,15 @@ module RailsBestPractices
144
150
  if node.arguments.all.last.hash_value('module').present?
145
151
  @namespaces << node.arguments.all.last.hash_value('module').to_s
146
152
  end
147
- if node.arguments.all.last.hash_value('controller').present?
148
- @controller_name = [:scope, node.arguments.all.last.hash_value('controller').to_s]
149
- else
150
- @controller_name = @controller_name.try(:first) == :scope ? @controller_name : nil
151
- end
153
+ @controller_name =
154
+ if node.arguments.all.last.hash_value('controller').present?
155
+ [:scope, node.arguments.all.last.hash_value('controller').to_s]
156
+ else
157
+ @controller_name.try(:first) == :scope ? @controller_name : nil
158
+ end
152
159
  when 'with_options'
153
160
  argument = node.arguments.all.last
154
- if :bare_assoc_hash == argument.sexp_type && argument.hash_value('controller').present?
161
+ if argument.sexp_type == :bare_assoc_hash && argument.hash_value('controller').present?
155
162
  @controller_name = [:with_option, argument.hash_value('controller').to_s]
156
163
  end
157
164
  else
@@ -15,7 +15,7 @@ module RailsBestPractices
15
15
  end
16
16
 
17
17
  add_callback :start_command do |node|
18
- if 'create_table' == node.message.to_s
18
+ if node.message.to_s == 'create_table'
19
19
  @last_klazz = node.arguments.all.first.to_s.classify
20
20
  end
21
21
  end
@@ -46,46 +46,50 @@ module RailsBestPractices
46
46
 
47
47
  private
48
48
 
49
- # check an attribute assignment node, if there is a array reference node in the right value of assignment node,
50
- # then remember this attribute assignment.
51
- def assign(node)
52
- left_value = node.left_value
53
- right_value = node.right_value
54
- return unless :field == left_value.sexp_type && :call == right_value.sexp_type
55
- aref_node = right_value.grep_node(sexp_type: :aref)
56
- if aref_node
57
- assignments(left_value.receiver.to_s) << { message: left_value.message.to_s, arguments: aref_node.to_s }
58
- end
59
- end
49
+ # check an attribute assignment node, if there is a array reference node in the right value of assignment node,
50
+ # then remember this attribute assignment.
51
+ def assign(node)
52
+ left_value = node.left_value
53
+ right_value = node.right_value
54
+ return unless left_value.sexp_type == :field && right_value.sexp_type == :call
60
55
 
61
- # check a call node with message "save" or "save!",
62
- # if there exists an attribute assignment for the receiver of this call node,
63
- # and if the arguments of this attribute assignments has duplicated entries (different message and same arguments),
64
- # then this node needs to add a virtual attribute.
65
- def call_assignment(node)
66
- if ['save', 'save!'].include? node.message.to_s
67
- receiver = node.receiver.to_s
68
- add_error "add model virtual attribute (for #{receiver})" if params_dup?(assignments(receiver).collect { |h| h[:arguments] })
69
- end
56
+ aref_node = right_value.grep_node(sexp_type: :aref)
57
+ if aref_node
58
+ assignments(left_value.receiver.to_s) << { message: left_value.message.to_s, arguments: aref_node.to_s }
70
59
  end
60
+ end
71
61
 
72
- # if the nodes are duplicated.
73
- def params_dup?(nodes)
74
- return false if nodes.nil?
75
- !dups(nodes).empty?
62
+ # check a call node with message "save" or "save!",
63
+ # if there exists an attribute assignment for the receiver of this call node,
64
+ # and if the arguments of this attribute assignments has duplicated entries (different message and same arguments),
65
+ # then this node needs to add a virtual attribute.
66
+ def call_assignment(node)
67
+ if ['save', 'save!'].include? node.message.to_s
68
+ receiver = node.receiver.to_s
69
+ add_error "add model virtual attribute (for #{receiver})" if params_dup?(
70
+ assignments(receiver).collect { |h| h[:arguments] }
71
+ )
76
72
  end
73
+ end
77
74
 
78
- # get the assignments of receiver.
79
- def assignments(receiver)
80
- @assignments[receiver] ||= []
81
- end
75
+ # if the nodes are duplicated.
76
+ def params_dup?(nodes)
77
+ return false if nodes.nil?
82
78
 
83
- # Get the duplicate entries from an Enumerable.
84
- #
85
- # @return [Enumerable] the duplicate entries.
86
- def dups(nodes)
87
- nodes.inject({}) { |h, v| h[v] = h[v].to_i + 1; h }.reject { |_k, v| v == 1 }.keys
88
- end
79
+ !dups(nodes).empty?
80
+ end
81
+
82
+ # get the assignments of receiver.
83
+ def assignments(receiver)
84
+ @assignments[receiver] ||= []
85
+ end
86
+
87
+ # Get the duplicate entries from an Enumerable.
88
+ #
89
+ # @return [Enumerable] the duplicate entries.
90
+ def dups(nodes)
91
+ nodes.each_with_object({}) { |v, h| h[v] = h[v].to_i + 1 }.reject { |_k, v| v == 1 }.keys
92
+ end
89
93
  end
90
94
  end
91
95
  end