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