rails_best_practices 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/.gitignore +1 -0
  2. data/README.md +11 -6
  3. data/assets/result.html.erb +76 -46
  4. data/install_supported_rubies.sh +3 -0
  5. data/lib/rails_best_practices.rb +2 -1
  6. data/lib/rails_best_practices/analyzer.rb +10 -8
  7. data/lib/rails_best_practices/core.rb +0 -4
  8. data/lib/rails_best_practices/core/check.rb +41 -117
  9. data/lib/rails_best_practices/core/error.rb +3 -9
  10. data/lib/rails_best_practices/core/runner.rb +20 -80
  11. data/lib/rails_best_practices/lexicals/long_line_check.rb +2 -1
  12. data/lib/rails_best_practices/lexicals/remove_tab_check.rb +1 -3
  13. data/lib/rails_best_practices/lexicals/remove_trailing_whitespace_check.rb +1 -3
  14. data/lib/rails_best_practices/prepares/config_prepare.rb +1 -1
  15. data/lib/rails_best_practices/prepares/controller_prepare.rb +7 -8
  16. data/lib/rails_best_practices/prepares/helper_prepare.rb +2 -2
  17. data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
  18. data/lib/rails_best_practices/prepares/model_prepare.rb +6 -7
  19. data/lib/rails_best_practices/prepares/route_prepare.rb +12 -13
  20. data/lib/rails_best_practices/prepares/schema_prepare.rb +2 -2
  21. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +19 -15
  22. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +10 -17
  23. data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +2 -5
  24. data/lib/rails_best_practices/reviews/hash_syntax_review.rb +3 -30
  25. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +7 -10
  26. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +5 -9
  27. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +10 -13
  28. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +6 -9
  29. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +2 -5
  30. data/lib/rails_best_practices/reviews/move_code_into_model_review.rb +7 -13
  31. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +3 -6
  32. data/lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb +6 -9
  33. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +3 -6
  34. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +4 -7
  35. data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +2 -5
  36. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +7 -10
  37. data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +2 -5
  38. data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +2 -5
  39. data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +8 -6
  40. data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +1 -2
  41. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +4 -5
  42. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +9 -12
  43. data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb +2 -13
  44. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +18 -26
  45. data/lib/rails_best_practices/reviews/review.rb +6 -7
  46. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -5
  47. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +2 -5
  48. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +2 -5
  49. data/lib/rails_best_practices/reviews/use_model_association_review.rb +11 -14
  50. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +11 -8
  51. data/lib/rails_best_practices/reviews/use_observer_review.rb +8 -11
  52. data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +1 -1
  53. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +12 -18
  54. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +7 -10
  55. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +4 -10
  56. data/lib/rails_best_practices/version.rb +1 -1
  57. data/rails_best_practices.gemspec +1 -1
  58. data/rails_best_practices.yml +5 -5
  59. data/spec/rails_best_practices/core/check_spec.rb +0 -67
  60. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +0 -1
  61. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +0 -4
  62. data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +3 -30
  63. data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +22 -0
  64. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +19 -0
  65. data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +2 -2
  66. data/spec/spec_helper.rb +0 -4
  67. metadata +28 -41
  68. data/Gemfile.lock +0 -71
  69. data/lib/rails_best_practices/core/checking_visitor.rb +0 -80
  70. data/lib/rails_best_practices/core/nil.rb +0 -37
  71. data/lib/rails_best_practices/core_ext/enumerable.rb +0 -9
  72. data/lib/rails_best_practices/core_ext/sexp.rb +0 -840
  73. data/spec/rails_best_practices/core/checking_visitor_spec.rb +0 -79
  74. data/spec/rails_best_practices/core/nil_spec.rb +0 -37
  75. data/spec/rails_best_practices/core_ext/enumerable_spec.rb +0 -7
  76. data/spec/rails_best_practices/core_ext/sexp_spec.rb +0 -613
@@ -17,22 +17,19 @@ module RailsBestPractices
17
17
  class RestrictAutoGeneratedRoutesReview < Review
18
18
  interesting_nodes :command, :command_call, :method_add_block
19
19
  interesting_files ROUTE_FILES
20
+ url "http://rails-bestpractices.com/posts/86-restrict-auto-generated-routes"
20
21
 
21
22
  RESOURCE_METHODS = ["show", "new", "create", "edit", "update", "destroy"]
22
23
  RESOURCES_METHODS = RESOURCE_METHODS + ["index"]
23
24
 
24
- def url
25
- "http://rails-bestpractices.com/posts/86-restrict-auto-generated-routes"
26
- end
27
-
28
25
  def initialize
29
26
  super
30
27
  @namespaces = []
31
28
  @resource_controllers = []
32
29
  end
33
30
 
34
- # check if the generated routes have the corresponding actions in controller for rails3 routes.
35
- def start_command(node)
31
+ # check if the generated routes have the corresponding actions in controller for rails routes.
32
+ add_callback :start_command, :start_command_call do |node|
36
33
  if "resources" == node.message.to_s
37
34
  check_resources(node)
38
35
  @resource_controllers << node.arguments.all.first.to_s
@@ -42,7 +39,7 @@ module RailsBestPractices
42
39
  end
43
40
  end
44
41
 
45
- def end_command(node)
42
+ add_callback :end_command do |node|
46
43
  if "resources" == node.message.to_s
47
44
  @resource_controllers.pop
48
45
  elsif "resource" == node.message.to_s
@@ -51,37 +48,32 @@ module RailsBestPractices
51
48
  end
52
49
 
53
50
  # remember the namespace.
54
- def start_method_add_block(node)
51
+ add_callback :start_method_add_block do |node|
55
52
  case node.message.to_s
56
53
  when "namespace"
57
- return unless check_method_add_block?(node)
58
- @namespaces << node.arguments.all.first.to_s
54
+ @namespaces << node.arguments.all.first.to_s if check_method_add_block?(node)
59
55
  when "resources", "resource"
60
- return unless check_method_add_block?(node)
61
- @resource_controllers << node.arguments.all.first.to_s
56
+ @resource_controllers << node.arguments.all.first.to_s if check_method_add_block?(node)
62
57
  else
63
58
  end
64
59
  end
65
60
 
66
61
  # end of namespace call.
67
- def end_method_add_block(node)
68
- return unless check_method_add_block?(node)
69
-
70
- case node.message.to_s
71
- when "namespace"
72
- @namespaces.pop
73
- when "resources", "resource"
74
- @resource_controllers.pop
62
+ add_callback :end_method_add_block do |node|
63
+ if check_method_add_block?(node)
64
+ case node.message.to_s
65
+ when "namespace"
66
+ @namespaces.pop
67
+ when "resources", "resource"
68
+ @resource_controllers.pop
69
+ end
75
70
  end
76
71
  end
77
72
 
78
73
  def check_method_add_block?(node)
79
- :command == node[1].sexp_type || (:command_call == node[1].sexp_type && "map" != node.subject.to_s)
74
+ :command == node[1].sexp_type || (:command_call == node[1].sexp_type && "map" != node.receiver.to_s)
80
75
  end
81
76
 
82
- # check if the generated routes have the corresponding actions in controller for rails2 routes.
83
- alias_method :start_command_call, :start_command
84
-
85
77
  private
86
78
  # check resources call, if the routes generated by resources does not exist in the controller.
87
79
  def check_resources(node)
@@ -143,7 +135,7 @@ module RailsBestPractices
143
135
  elsif hash_key_exist?(option_node, "except")
144
136
  if option_node.hash_value("except").to_s == "all"
145
137
  []
146
- else
138
+ else
147
139
  (methods - Array(option_node.hash_value("except").to_object))
148
140
  end
149
141
  else
@@ -165,7 +157,7 @@ module RailsBestPractices
165
157
  elsif hash_key_exist?(option_node, "except")
166
158
  if option_node.hash_value("except").to_s == "all"
167
159
  []
168
- else
160
+ else
169
161
  (methods - Array(option_node.hash_value("except").to_object))
170
162
  end
171
163
  else
@@ -7,9 +7,8 @@ module RailsBestPractices
7
7
  # A Review class that takes charge of reviewing one rails best practice.
8
8
  class Review < Core::Check
9
9
  # default url.
10
- def url
11
- "#"
12
- end
10
+ url "#"
11
+
13
12
  # remember use count for the variable in the call or assign node.
14
13
  #
15
14
  # find the variable in the call or assign node,
@@ -35,11 +34,11 @@ module RailsBestPractices
35
34
 
36
35
  # find variable in the call or field node.
37
36
  def variable(node)
38
- while [:call, :field, :method_add_arg, :method_add_block].include?(node.subject.sexp_type)
39
- node = node.subject
37
+ while [:call, :field, :method_add_arg, :method_add_block].include?(node.receiver.sexp_type)
38
+ node = node.receiver
40
39
  end
41
- return if [:fcall, :hash].include?(node.subject.sexp_type)
42
- node.subject
40
+ return if [:fcall, :hash].include?(node.receiver.sexp_type)
41
+ node.receiver
43
42
  end
44
43
 
45
44
  # get the models from Prepares.
@@ -16,15 +16,12 @@ module RailsBestPractices
16
16
  class SimplifyRenderInControllersReview < Review
17
17
  interesting_nodes :command
18
18
  interesting_files CONTROLLER_FILES
19
-
20
- def url
21
- "http://rails-bestpractices.com/posts/62-simplify-render-in-controllers"
22
- end
19
+ url "http://rails-bestpractices.com/posts/62-simplify-render-in-controllers"
23
20
 
24
21
  # check command node in the controller file,
25
22
  # if its message is render and the arguments contain a key action, template or file,
26
23
  # then it should be replaced by simplified syntax.
27
- def start_command(node)
24
+ add_callback :start_command do |node|
28
25
  if "render" == node.message.to_s
29
26
  keys = node.arguments.all.first.hash_keys
30
27
  if keys && keys.size == 1 &&
@@ -15,17 +15,14 @@ module RailsBestPractices
15
15
  class SimplifyRenderInViewsReview < Review
16
16
  interesting_nodes :command
17
17
  interesting_files VIEW_FILES
18
+ url "http://rails-bestpractices.com/posts/61-simplify-render-in-views"
18
19
 
19
20
  VALID_KEYS = %w(object collection locals)
20
21
 
21
- def url
22
- "http://rails-bestpractices.com/posts/61-simplify-render-in-views"
23
- end
24
-
25
22
  # check command node in view file,
26
23
  # if its message is render and the arguments contain a key partial,
27
24
  # then it should be replaced by simplified syntax.
28
- def start_command(node)
25
+ add_callback :start_command do |node|
29
26
  if "render" == node.message.to_s
30
27
  hash_node = node.arguments.all.first
31
28
  if hash_node && :bare_assoc_hash == hash_node.sexp_type &&
@@ -16,10 +16,7 @@ module RailsBestPractices
16
16
  class UseBeforeFilterReview < Review
17
17
  interesting_nodes :class
18
18
  interesting_files CONTROLLER_FILES
19
-
20
- def url
21
- "http://rails-bestpractices.com/posts/22-use-before_filter"
22
- end
19
+ url "http://rails-bestpractices.com/posts/22-use-before_filter"
23
20
 
24
21
  def initialize(options = {})
25
22
  super()
@@ -31,7 +28,7 @@ module RailsBestPractices
31
28
  # it will check every def nodes in the class node until protected or private identification,
32
29
  # if there are defn nodes who have the same first code line,
33
30
  # then these duplicated first code lines should be moved to before_filter.
34
- def start_class(node)
31
+ add_callback :start_class do |node|
35
32
  @first_sentences = {}
36
33
 
37
34
  node.body.statements.each do |statement_node|
@@ -13,26 +13,23 @@ module RailsBestPractices
13
13
  # check model define nodes in all controller files,
14
14
  # if there is an attribute assignment node with message xxx_id=,
15
15
  # and after it, there is a call node with message "save" or "save!",
16
- # and the subjects of attribute assignment node and call node are the same,
16
+ # and the receivers of attribute assignment node and call node are the same,
17
17
  # then model association should be used instead of xxx_id assignment.
18
18
  class UseModelAssociationReview < Review
19
19
  interesting_nodes :def
20
20
  interesting_files CONTROLLER_FILES
21
-
22
- def url
23
- "http://rails-bestpractices.com/posts/2-use-model-association"
24
- end
21
+ url "http://rails-bestpractices.com/posts/2-use-model-association"
25
22
 
26
23
  # check method define nodes to see if there are some attribute assignments that can use model association instead.
27
24
  #
28
25
  # it will check attribute assignment node with message xxx_id=, and call node with message "save" or "save!"
29
26
  #
30
27
  # 1. if there is an attribute assignment node with message xxx_id=,
31
- # then remember the subject of attribute assignment node.
28
+ # then remember the receiver of attribute assignment node.
32
29
  # 2. after assignment, if there is a call node with message "save" or "save!",
33
- # and the subject of call node is one of the subject of attribute assignment node,
30
+ # and the receiver of call node is one of the receiver of attribute assignment node,
34
31
  # then the attribute assignment should be replaced by using model association.
35
- def start_def(node)
32
+ add_callback :start_def do |node|
36
33
  @assignments = {}
37
34
  node.recursive_children do |child|
38
35
  case child.sexp_type
@@ -48,21 +45,21 @@ module RailsBestPractices
48
45
 
49
46
  private
50
47
  # check an attribute assignment node, if its message is xxx_id,
51
- # then remember the subject of the attribute assignment in @assignments.
48
+ # then remember the receiver of the attribute assignment in @assignments.
52
49
  def attribute_assignment(node)
53
50
  if node.left_value.message.to_s =~ /_id$/
54
- subject = node.left_value.subject.to_s
55
- @assignments[subject] = true
51
+ receiver = node.left_value.receiver.to_s
52
+ @assignments[receiver] = true
56
53
  end
57
54
  end
58
55
 
59
56
  # check a call node with message "save" or "save!",
60
- # if the subject of call node exists in @assignments,
57
+ # if the receiver of call node exists in @assignments,
61
58
  # then the attribute assignment should be replaced by using model association.
62
59
  def call_assignment(node)
63
60
  if ["save", "save!"].include? node.message.to_s
64
- subject = node.subject.to_s
65
- add_error "use model association (for #{subject})" if @assignments[subject]
61
+ receiver = node.receiver.to_s
62
+ add_error "use model association (for #{receiver})" if @assignments[receiver]
66
63
  end
67
64
  end
68
65
  end
@@ -17,26 +17,29 @@ module RailsBestPractices
17
17
  class UseMultipartAlternativeAsContentTypeOfEmailReview < Review
18
18
  interesting_nodes :class, :def
19
19
  interesting_files MAILER_FILES
20
-
21
- def url
22
- "http://rails-bestpractices.com/posts/41-use-multipart-alternative-as-content_type-of-email"
23
- end
20
+ url "http://rails-bestpractices.com/posts/41-use-multipart-alternative-as-content_type-of-email"
24
21
 
25
22
  # check class node to remember the ActionMailer class name.
26
- def start_class(node)
23
+ add_callback :start_class do |node|
27
24
  @klazz_name = node.class_name.to_s
28
25
  end
29
26
 
30
27
  # check def node and find if the corresponding views exist or not?
31
- def start_def(node)
28
+ add_callback :start_def do |node|
32
29
  name = node.method_name.to_s
33
- return unless deliver_method?(name)
34
- if rails2_canonical_mailer_views?(name) || rails3_canonical_mailer_views?(name)
30
+ if deliver_method?(name) && rails_canonical_mailer_views?(name)
35
31
  add_error("use multipart/alternative as content_type of email")
36
32
  end
37
33
  end
38
34
 
39
35
  private
36
+ # check if rails's syntax mailer views are canonical.
37
+ #
38
+ # @param [String] name method name in action_mailer
39
+ def rails_canonical_mailer_views?(name)
40
+ rails2_canonical_mailer_views?(name) || rails3_canonical_mailer_views?(name)
41
+ end
42
+
40
43
  # check if rails2's syntax mailer views are canonical.
41
44
  #
42
45
  # @param [String] name method name in action_mailer
@@ -22,10 +22,7 @@ module RailsBestPractices
22
22
  class UseObserverReview < Review
23
23
  interesting_nodes :def, :command
24
24
  interesting_files MODEL_FILES
25
-
26
- def url
27
- "http://rails-bestpractices.com/posts/19-use-observer"
28
- end
25
+ url "http://rails-bestpractices.com/posts/19-use-observer"
29
26
 
30
27
  def initialize
31
28
  super
@@ -36,7 +33,7 @@ module RailsBestPractices
36
33
  #
37
34
  # if it is a callback definition,
38
35
  # then remember its callback methods.
39
- def start_command(node)
36
+ add_callback :start_command do |node|
40
37
  remember_callback(node)
41
38
  end
42
39
 
@@ -45,7 +42,7 @@ module RailsBestPractices
45
42
  # if it is callback method,
46
43
  # and there is a actionmailer deliver call in the method define node,
47
44
  # then it should be replaced by using observer.
48
- def start_def(node)
45
+ add_callback :start_def do |node|
49
46
  if callback_method?(node) && deliver_mailer?(node)
50
47
  add_error "use observer"
51
48
  end
@@ -73,22 +70,22 @@ module RailsBestPractices
73
70
  # for rails2
74
71
  #
75
72
  # if the message of call node is deliver_xxx,
76
- # and the subject of the call node exists in @callbacks,
73
+ # and the receiver of the call node exists in @callbacks,
77
74
  #
78
75
  # for rails3
79
76
  #
80
77
  # if the message of call node is deliver,
81
- # and the subject of the call node is with subject node who exists in @callbacks,
78
+ # and the receiver of the call node is with receiver node who exists in @callbacks,
82
79
  #
83
80
  # then the call node is actionmailer deliver call.
84
81
  def deliver_mailer?(node)
85
82
  node.grep_nodes(sexp_type: :call) do |child_node|
86
83
  # rails2 actionmailer deliver
87
- return true if child_node.message.to_s =~ /^deliver_/ && mailers.include?(child_node.subject.to_s)
84
+ return true if child_node.message.to_s =~ /^deliver_/ && mailers.include?(child_node.receiver.to_s)
88
85
  # rails3 actionmailer deliver
89
86
  if "deliver" == child_node.message.to_s
90
- if :method_add_arg == child_node.subject.sexp_type &&
91
- mailers.include?(child_node.subject[1].subject.to_s)
87
+ if :method_add_arg == child_node.receiver.sexp_type &&
88
+ mailers.include?(child_node.receiver[1].receiver.to_s)
92
89
  return true
93
90
  end
94
91
  end
@@ -14,7 +14,7 @@ module RailsBestPractices
14
14
  interesting_files ALL_FILES
15
15
 
16
16
  # check def node to see if parameters are wrapped by parentheses.
17
- def start_def(node)
17
+ add_callback :start_def do |node|
18
18
  if no_parentheses_around_parameters?(node) && has_parameters?(node)
19
19
  add_error("use parentheses around parameters in method definitions")
20
20
  end
@@ -11,33 +11,30 @@ module RailsBestPractices
11
11
  #
12
12
  # Review process:
13
13
  # check all method calls within conditional statements, like @user.login.nil?
14
- # if their subjects are one of the model names
14
+ # if their receivers are one of the model names
15
15
  # and their messages of first call are not pluralize and not in any of the association names
16
16
  # and their messages of second call are one of nil?, blank?, present?, or they are == ""
17
17
  # then you can use query attribute instead.
18
18
  class UseQueryAttributeReview < Review
19
19
  interesting_nodes :if, :unless, :elsif
20
20
  interesting_files ALL_FILES
21
+ url "http://rails-bestpractices.com/posts/56-use-query-attribute"
21
22
 
22
23
  QUERY_METHODS = %w(nil? blank? present?)
23
24
 
24
- def url
25
- "http://rails-bestpractices.com/posts/56-use-query-attribute"
26
- end
27
-
28
25
  # check if node to see whose conditional statement nodes contain nodes that can use query attribute instead.
29
26
  #
30
27
  # it will check every call nodes in the if nodes. If the call node is
31
28
  #
32
29
  # 1. two method calls, like @user.login.nil?
33
- # 2. the subject is one of the model names
30
+ # 2. the receiver is one of the model names
34
31
  # 3. the message of first call is the model's attribute,
35
32
  # the message is not in any of associations name and is not pluralize
36
33
  # 4. the message of second call is one of nil?, blank? or present? or
37
34
  # the message is == and the argument is ""
38
35
  #
39
36
  # then the call node can use query attribute instead.
40
- def start_if(node)
37
+ add_callback :start_if, :start_unless, :start_elsif do |node|
41
38
  all_conditions = if node.conditional_statement == node.conditional_statement.all_conditions
42
39
  [node.conditional_statement]
43
40
  else
@@ -45,17 +42,14 @@ module RailsBestPractices
45
42
  end
46
43
  all_conditions.each do |condition_node|
47
44
  if query_attribute_node = query_attribute_node(condition_node)
48
- subject_node = query_attribute_node.subject
49
- add_error "use query attribute (#{subject_node.subject}.#{subject_node.message}?)",
45
+ receiver_node = query_attribute_node.receiver
46
+ add_error "use query attribute (#{receiver_node.receiver}.#{receiver_node.message}?)",
50
47
  node.file,
51
48
  query_attribute_node.line
52
49
  end
53
50
  end
54
51
  end
55
52
 
56
- alias_method :start_unless, :start_if
57
- alias_method :start_elsif, :start_if
58
-
59
53
  private
60
54
  # recursively check conditional statement nodes to see if there is a call node that may be
61
55
  # possible query attribute.
@@ -81,7 +75,7 @@ module RailsBestPractices
81
75
  #
82
76
  # if the node contains two method calls, e.g. @user.login.nil?
83
77
  #
84
- # for the first call, the subject should be one of the class names and
78
+ # for the first call, the receiver should be one of the class names and
85
79
  # the message should be one of the attribute name.
86
80
  #
87
81
  # for the second call, the message should be one of nil?, blank? or present? or
@@ -89,23 +83,23 @@ module RailsBestPractices
89
83
  #
90
84
  # the node that may use query attribute.
91
85
  def possible_query_attribute?(node)
92
- return false unless :call == node.subject.sexp_type
86
+ return false unless :call == node.receiver.sexp_type
93
87
  variable_node = variable(node)
94
- message_node = node.grep_node(subject: variable_node.to_s).message
88
+ message_node = node.grep_node(receiver: variable_node.to_s).message
95
89
 
96
90
  is_model?(variable_node) && model_attribute?(variable_node, message_node.to_s) &&
97
91
  (QUERY_METHODS.include?(node.message.to_s) || compare_with_empty_string?(node))
98
92
  end
99
93
 
100
- # check if the subject is one of the models.
94
+ # check if the receiver is one of the models.
101
95
  def is_model?(variable_node)
102
96
  return false if variable_node.const?
103
97
  class_name = variable_node.to_s.sub(/^@/, '').classify
104
98
  models.include?(class_name)
105
99
  end
106
100
 
107
- # check if the subject and message is one of the model's attribute.
108
- # the subject should match one of the class model name, and the message should match one of attribute name.
101
+ # check if the receiver and message is one of the model's attribute.
102
+ # the receiver should match one of the class model name, and the message should match one of attribute name.
109
103
  def model_attribute?(variable_node, message)
110
104
  class_name = variable_node.to_s.sub(/^@/, '').classify
111
105
  attribute_type = model_attributes.get_attribute_type(class_name, message)