rails_best_practices 1.10.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
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)