rails_best_practices 0.10.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.md +20 -0
  2. data/assets/result.html.haml +1 -1
  3. data/lib/rails_best_practices.rb +5 -3
  4. data/lib/rails_best_practices/core.rb +1 -1
  5. data/lib/rails_best_practices/core/check.rb +9 -12
  6. data/lib/rails_best_practices/core/checking_visitor.rb +9 -6
  7. data/lib/rails_best_practices/core/model_associations.rb +1 -1
  8. data/lib/rails_best_practices/core/nil.rb +5 -1
  9. data/lib/rails_best_practices/core/runner.rb +5 -5
  10. data/lib/rails_best_practices/core_ext/sexp.rb +688 -0
  11. data/lib/rails_best_practices/prepares/mailer_prepare.rb +4 -5
  12. data/lib/rails_best_practices/prepares/model_prepare.rb +16 -26
  13. data/lib/rails_best_practices/prepares/schema_prepare.rb +11 -17
  14. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +24 -75
  15. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +39 -113
  16. data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +6 -16
  17. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +16 -32
  18. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +11 -20
  19. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +7 -28
  20. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +16 -14
  21. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +10 -28
  22. data/lib/rails_best_practices/reviews/move_code_into_model_review.rb +12 -11
  23. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +13 -24
  24. data/lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb +9 -9
  25. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +24 -68
  26. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +15 -22
  27. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +31 -91
  28. data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -2
  29. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +20 -18
  30. data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb +5 -3
  31. data/lib/rails_best_practices/reviews/review.rb +8 -37
  32. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +10 -6
  33. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +9 -6
  34. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +14 -72
  35. data/lib/rails_best_practices/reviews/use_model_association_review.rb +19 -31
  36. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +5 -5
  37. data/lib/rails_best_practices/reviews/use_observer_review.rb +22 -40
  38. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +34 -39
  39. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +14 -38
  40. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +13 -44
  41. data/lib/rails_best_practices/version.rb +1 -1
  42. data/spec/rails_best_practices/core/check_spec.rb +5 -5
  43. data/spec/rails_best_practices/core/checking_visitor_spec.rb +4 -4
  44. data/spec/rails_best_practices/core/model_associations_spec.rb +4 -4
  45. data/spec/rails_best_practices/core/nil_spec.rb +7 -1
  46. data/spec/rails_best_practices/core_ext/sexp_spec.rb +430 -0
  47. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +12 -12
  48. data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +6 -6
  49. data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +14 -2
  50. data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +1 -1
  51. data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +3 -3
  52. data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +1 -1
  53. data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +15 -1
  54. data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +3 -3
  55. data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +1 -1
  56. data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +1 -1
  57. data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +4 -4
  58. data/spec/rails_best_practices_spec.rb +1 -3
  59. data/spec/spec_helper.rb +4 -0
  60. metadata +6 -8
  61. data/lib/rails_best_practices/core/visitable_sexp.rb +0 -444
  62. data/spec/rails_best_practices/core/visitable_sexp_spec.rb +0 -272
  63. data/spec/rails_best_practices/reviews/review_spec.rb +0 -11
@@ -11,8 +11,8 @@ module RailsBestPractices
11
11
  #
12
12
  # Review process:
13
13
  # check all method defines in the controller files,
14
- # if there are multiple method calls or attribute assignments apply to one subject,
15
- # and the subject is a local variable or an instance variable,
14
+ # if there are multiple method calls apply to one subject,
15
+ # and the subject is a variable,
16
16
  # then they are complex model logic, and they should be moved into model.
17
17
  class MoveModelLogicIntoModelReview < Review
18
18
  def url
@@ -20,7 +20,7 @@ module RailsBestPractices
20
20
  end
21
21
 
22
22
  def interesting_nodes
23
- [:defn]
23
+ [:def]
24
24
  end
25
25
 
26
26
  def interesting_files
@@ -32,14 +32,14 @@ module RailsBestPractices
32
32
  @use_count = options['use_count'] || 4
33
33
  end
34
34
 
35
- # check method define node to see if there are multiple method calls and attribute assignments (more than @use_count defined) on one local variable or instance varialbe.
35
+ # check method define node to see if there are multiple method calls on one varialbe.
36
36
  #
37
- # it will check every call and attrasgn nodes,
38
- # if there are multiple call and attrasgn nodes who have the same subject,
39
- # and the subject is a local variable or an instance variable,
37
+ # it will check every call nodes,
38
+ # if there are multiple call nodes who have the same subject,
39
+ # and the subject is a variable,
40
40
  # then these method calls and attribute assignments should be moved into model.
41
- def start_defn(node)
42
- node.grep_nodes(:node_type => [:call, :attrasgn]) do |child_node|
41
+ def start_def(node)
42
+ node.grep_nodes(:sexp_type => [:call, :assign]) do |child_node|
43
43
  remember_variable_use_count(child_node)
44
44
  end
45
45
 
@@ -10,20 +10,17 @@ module RailsBestPractices
10
10
  # Implementation:
11
11
  #
12
12
  # Review process:
13
- # chech all iter nodes in route file.
13
+ # chech all method_add_block nodes in route file.
14
14
  #
15
- # it is a recursively check in :iter node,
15
+ # it is a recursively check in method_add_block node,
16
16
  #
17
- # if it is a :iter node,
17
+ # if it is a method_add_block node,
18
18
  # increment @counter at the beginning of resources,
19
19
  # decrement @counter at the end of resrouces,
20
- # recursively check nodes in iter's block body.
20
+ # recursively check nodes in block body.
21
21
  #
22
- # if it is a :block node,
23
- # then recursively check all child nodes in block node.
24
- #
25
- # if it is a :call node,
26
- # and the message of the node is :resources or :resource,
22
+ # if the child node is a command_call or command node,
23
+ # and the message of the node is "resources" or "resource",
27
24
  # and the @counter is greater than @nested_count defined,
28
25
  # then it is a needless deep nesting.
29
26
  class NeedlessDeepNestingReview < Review
@@ -32,7 +29,7 @@ module RailsBestPractices
32
29
  end
33
30
 
34
31
  def interesting_nodes
35
- [:call, :iter]
32
+ [:method_add_block]
36
33
  end
37
34
 
38
35
  def interesting_files
@@ -45,83 +42,42 @@ module RailsBestPractices
45
42
  @nested_count = options['nested_count'] || 2
46
43
  end
47
44
 
48
- # check all iter node.
49
- #
50
- # It is a recursively check,
45
+ # check all method_add_block node.
51
46
  #
52
- # if it is a :iter node, like
53
- #
54
- # resources posts do
55
- # ...
56
- # end
47
+ # It is a recursively check, if it is a method_add_block node,
57
48
  # increment @counter at the beginning of resources,
58
- # decrement @counter at the end of iter resources,
49
+ # decrement @counter at the end of method_add_block resources,
59
50
  # recursively check the block body.
60
51
  #
61
- # if it is a :block node, like
62
- #
63
- # resources :posts do
64
- # resources :comments
65
- # resources :votes
66
- # end
67
- #
68
- # just recursively check each child node in block node.
69
- #
70
- # if it is a :call node with message :resources or :resource, like
71
- #
72
- # resources :comments
73
- #
52
+ # if the child node is a command_call or command node with message "resources" or "resource",
74
53
  # test if the @counter is greater than or equal to @nested_count,
75
54
  # if so, it is a needless deep nesting.
76
- def start_iter(node)
55
+ def start_method_add_block(node)
56
+ @file = node.file
77
57
  recursively_check(node)
78
58
  end
79
59
 
80
60
  private
81
61
  # check nested route.
82
62
  #
83
- # if the node type is :iter,
84
- # and the subject of the node is with message :resources or :resource, like
85
- #
86
- # s(:iter,
87
- # s(:call, nil, :resources,
88
- # s(:arglist, s(:lit, :posts))
89
- # ),
90
- # nil,
91
- # s(:call, nil, :resources,
92
- # s(:arglist, s(:lit, :comments))
93
- # )
94
- # )
95
- #
63
+ # if the subject of the method_add_block is with message "resources" or "resource",
96
64
  # then increment the @counter, recursively check the block body, and decrement the @counter.
97
65
  #
98
- # if the node type is :block, it is the block body of :iter node, like
99
- #
100
- # s(:block,
101
- # s(:call, nil, :resources, s(:arglist, s(:lit, :comments))),
102
- # s(:call, nil, :resources, s(:arglist, s(:lit, :votes)))
103
- # )
104
- #
105
- # then check the each child node in the block.
106
- #
107
- # if the node type is :call,
108
- # and the message of node is :resources or :resource, like
109
- #
110
- # s(:call, nil, :resources, s(:arglist, s(:lit, :comments)))
111
- #
66
+ # if the node type is command_call or command,
67
+ # and its message is resources or resource,
112
68
  # then check if @counter is greater than or equal to @nested_count,
113
69
  # if so, it is the needless deep nesting.
114
70
  def recursively_check(node)
115
- if :iter == node.node_type && :resources == node.subject.message
116
- options = eval(node.subject.arguments[2].to_s)
117
- return if options && options["shallow"] == true
71
+ if [:command_call, :command].include?(node[1].sexp_type) && ["resources", "resource"].include?(node[1].message.to_s)
72
+ hash_node = node[1].arguments.grep_node(:sexp_type => :bare_assoc_hash)
73
+ return if hash_node && "true" == hash_node.hash_value("shallow").to_s
118
74
  @counter += 1
119
- recursively_check(node.body)
75
+ node.block.statements.each do |stmt_node|
76
+ recursively_check(stmt_node)
77
+ end
120
78
  @counter -= 1
121
- elsif :block == node.node_type
122
- node.children.each { |child_node| recursively_check(child_node) }
123
- elsif :call == node.node_type && [:resources, :resource].include?(node.message)
124
- add_error "needless deep nesting (nested_count > #{@nested_count})", node.file, node.line if @counter >= @nested_count
79
+ elsif [:command_call, :command].include?(node.sexp_type) && ["resources", "resource"].include?(node.message.to_s)
80
+ add_error "needless deep nesting (nested_count > #{@nested_count})", @file, node.line if @counter >= @nested_count
125
81
  end
126
82
  end
127
83
  end
@@ -10,7 +10,7 @@ module RailsBestPractices
10
10
  # Implementation:
11
11
  #
12
12
  # Review process:
13
- # check all method call to see if any method call is the same as rails default route.
13
+ # check all method command_call or command node to see if it is the same as rails default route.
14
14
  #
15
15
  # map.connect ':controller/:action/:id'
16
16
  # map.connect ':controller/:action/:id.:format'
@@ -24,33 +24,26 @@ module RailsBestPractices
24
24
  end
25
25
 
26
26
  def interesting_nodes
27
- [:call]
27
+ [:command_call, :command]
28
28
  end
29
29
 
30
30
  def interesting_files
31
31
  ROUTE_FILE
32
32
  end
33
33
 
34
- # check all method calls, it just compare with rails default route
35
- #
36
- # rails2
37
- #
38
- # s(:call, s(:lvar, :map), :connect,
39
- # s(:arglist, s(:str, ":controller/:action/:id"))
40
- # )
41
- # s(:call, s(:lvar, :map), :connect,
42
- # s(:arglist, s(:str, ":controller/:action/:id.:format"))
43
- # )
44
- #
45
- # rails3
46
- #
47
- # s(:call, nil, :match,
48
- # s(:arglist, s(:str, ":controller(/:action(/:id(.:format)))"))
49
- # )
50
- def start_call(node)
51
- if s(:call, s(:lvar, :map), :connect, s(:arglist, s(:str, ":controller/:action/:id"))) == node ||
52
- s(:call, s(:lvar, :map), :connect, s(:arglist, s(:str, ":controller/:action/:id.:format"))) == node ||
53
- s(:call, nil, :match, s(:arglist, s(:str, ":controller(/:action(/:id(.:format)))"))) == node
34
+ # check all command call nodes, compare with rails2 default route
35
+ def start_command_call(node)
36
+ if "map" == node.subject.to_s && "connect" == node.message.to_s &&
37
+ (":controller/:action/:id" == node.arguments.all[0].to_s ||
38
+ ":controller/:action/:id.:format" == node.arguments.all[0].to_s)
39
+ add_error "not use default route"
40
+ end
41
+ end
42
+
43
+ # check all command nodes, compare with rails3 default route
44
+ def start_command(node)
45
+ if "match" == node.message.to_s &&
46
+ ":controller(/:action(/:id(.:format)))" == node.arguments.all[0].to_s
54
47
  add_error "not use default route"
55
48
  end
56
49
  end
@@ -14,29 +14,29 @@ module RailsBestPractices
14
14
  #
15
15
  # for rails2
16
16
  #
17
- # check all call nodes in route file.
18
- # if the message of call node is resources,
19
- # and the second argument of call node is a hash,
17
+ # check all command_call nodes in route file.
18
+ # if the message of command_call node is resources,
19
+ # and the second argument of command_call node is a hash,
20
20
  # and the count of the pair (key/value) in hash is greater than @customize_count,
21
21
  # then these custom routes are overuse.
22
22
  #
23
23
  # for rails3
24
24
  #
25
- # check all iter nodes in route file.
26
- # if the subject of iter node is with message resources,
27
- # and in the block body of iter node, there are more than @customize_count call nodes,
28
- # whose message is :get, :post, :update or :delete,
25
+ # check all method_add_block nodes in route file.
26
+ # if the subject of method_add_block node is with message resources,
27
+ # and in the block body of method_add_block node, there are more than @customize_count command nodes,
28
+ # whose message is get, post, update or delete,
29
29
  # then these custom routes are overuse.
30
30
  class OveruseRouteCustomizationsReview < Review
31
31
 
32
- VERBS = [:get, :post, :update, :delete]
32
+ VERBS = %w(get post update delete)
33
33
 
34
34
  def url
35
35
  "http://rails-bestpractices.com/posts/10-overuse-route-customizations"
36
36
  end
37
37
 
38
38
  def interesting_nodes
39
- [:call, :iter]
39
+ [:command_call, :method_add_block]
40
40
  end
41
41
 
42
42
  def interesting_files
@@ -48,120 +48,60 @@ module RailsBestPractices
48
48
  @customize_count = options['customize_count'] || 3
49
49
  end
50
50
 
51
- # check call node to see if the count of member and collection custom routes is more than @customize_count defined.
51
+ # check command_call node to see if the count of member and collection custom routes is more than @customize_count defined.
52
52
  # this is for rails2 syntax.
53
53
  #
54
- # if the message of call node is :resources,
54
+ # if the message of call node is "resources",
55
55
  # and the second argument of call node is a hash,
56
- # and the count of the pair (key/value) in hash is greater than @customize_count, like
57
- #
58
- # map.resources :posts, :member => { :create_comment => :post,
59
- # :update_comment => :update,
60
- # :delete_comment => :delete },
61
- # :collection => { :comments => :get }
62
- #
56
+ # and the count of the pair (key/value) in hash is greater than @customize_count,
63
57
  # then they are overuse route customizations.
64
- def start_call(node)
58
+ def start_command_call(node)
65
59
  if member_and_collection_count_for_rails2(node) > @customize_count
66
60
  add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.subject.line
67
61
  end
68
62
  end
69
63
 
70
- # check iter node to see if the count of member and collection custom routes is more than @customize_count defined.
64
+ # check method_add_block node to see if the count of member and collection custom routes is more than @customize_count defined.
71
65
  # this is for rails3 syntax.
72
66
  #
73
- # if the subject of iter node is with message :resources,
74
- # and in the block body of iter node, there are more than @customize_count call nodes,
75
- # whose message is :get, :post, :update or :delete, like
76
- #
77
- # resources :posts do
78
- # member do
79
- # post :create_comment
80
- # update :update_comment
81
- # delete :delete_comment
82
- # end
83
- #
84
- # collection do
85
- # get :comments
86
- # end
87
- # end
88
- #
67
+ # if the subject of method_add_block node is with message "resources",
68
+ # and in the block body of method_add_block node, there are more than @customize_count call nodes,
69
+ # whose message is :get, :post, :update or :delete,
89
70
  # then they are overuse route customizations.
90
- def start_iter(node)
71
+ def start_method_add_block(node)
91
72
  if member_and_collection_count_for_rails3(node) > @customize_count
92
- add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.subject.line
73
+ add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.line
93
74
  end
94
75
  end
95
76
 
96
77
  private
97
- # check call node to calculate the count of member and collection custom routes.
78
+ # check command_call node to calculate the count of member and collection custom routes.
98
79
  # this is for rails2 syntax.
99
80
  #
100
- # if the message of call node is :resources,
81
+ # if the message of command_call node is "resources",
101
82
  # and the second argument is a hash,
102
83
  # then calculate the pair (key/value) count,
103
84
  # it is just the count of member and collection custom routes.
104
- #
105
- # s(:call, s(:lvar, :map), :resources,
106
- # s(:arglist,
107
- # s(:lit, :posts),
108
- # s(:hash,
109
- # s(:lit, :member),
110
- # s(:hash,
111
- # s(:lit, :create_comment),
112
- # s(:lit, :post),
113
- # s(:lit, :update_comment),
114
- # s(:lit, :update),
115
- # s(:lit, :delete_comment),
116
- # s(:lit, :delete)
117
- # ),
118
- # s(:lit, :collection),
119
- # s(:hash,
120
- # s(:lit, :comments),
121
- # s(:lit, :get)
122
- # )
123
- # )
124
- # )
125
- # )
126
85
  def member_and_collection_count_for_rails2(node)
127
- if :resources == node.message
128
- hash_node = node.arguments[2]
129
- if hash_node
130
- return (hash_node.grep_nodes_count(:node_type => :lit) - hash_node.grep_nodes_count(:node_type => :hash)) / 2
86
+ if "resources" == node.message.to_s
87
+ hash_node = node.arguments.all[1]
88
+ if hash_node && :bare_assoc_hash == hash_node.sexp_type
89
+ member_node = hash_node.hash_value("member")
90
+ collection_node = hash_node.hash_value("collection")
91
+ return (member_node.hash_size || member_node.array_size) + (collection_node.hash_size || collection_node.array_size)
131
92
  end
132
93
  end
133
94
  0
134
95
  end
135
96
 
136
- # check iter node to calculate the count of member and collection custom routes.
97
+ # check method_add_block node to calculate the count of member and collection custom routes.
137
98
  # this is for rails3 syntax.
138
99
  #
139
- # if its subject is with message :resources,
140
- # then calculate the count of call nodes, whose message is :get, :post, :update or :delete,
100
+ # if its subject is with message "resources",
101
+ # then calculate the count of call nodes, whose message is get, post, update or delete,
141
102
  # it is just the count of member and collection custom routes.
142
- #
143
- # s(:iter,
144
- # s(:call, nil, :resources, s(:arglist, s(:lit, :posts))),
145
- # nil,
146
- # s(:block,
147
- # s(:iter,
148
- # s(:call, nil, :member, s(:arglist)),
149
- # nil,
150
- # s(:block,
151
- # s(:call, nil, :post, s(:arglist, s(:lit, :create_comment))),
152
- # s(:call, nil, :post, s(:arglist, s(:lit, :update_comment))),
153
- # s(:call, nil, :post, s(:arglist, s(:lit, :delete_comment)))
154
- # )
155
- # ),
156
- # s(:iter,
157
- # s(:call, nil, :collection, s(:arglist)),
158
- # nil,
159
- # s(:call, nil, :get, s(:arglist, s(:lit, :comments)))
160
- # )
161
- # )
162
- # )
163
103
  def member_and_collection_count_for_rails3(node)
164
- :resources == node.subject.message ? node.grep_nodes_count(:node_type => :call, :message => VERBS) : 0
104
+ "resources" == node[1].message.to_s ? node.grep_nodes_count(:sexp_type => :command, :message => VERBS) : 0
165
105
  end
166
106
  end
167
107
  end
@@ -25,8 +25,10 @@ module RailsBestPractices
25
25
  end
26
26
 
27
27
  # check the body of module node, if it is nil, then it should be removed.
28
- def start_module(module_node)
29
- add_error "remove empty helpers" if module_node.body.is_a?(Core::Nil)
28
+ def start_module(node)
29
+ if s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil) == node.body
30
+ add_error "remove empty helpers", node.file, node.line
31
+ end
30
32
  end
31
33
  end
32
34
  end
@@ -12,8 +12,8 @@ module RailsBestPractices
12
12
  # Review process:
13
13
  # check all method defines in the controller files,
14
14
  # if there are multiple attribute assignments apply to one subject,
15
- # and the subject is a local variable or an instance variable,
16
- # and after them there is a call node with message :save or :save!,
15
+ # and the subject is a variable,
16
+ # and after them there is a call node with message "save" or "save!",
17
17
  # then these attribute assignments are complex creation, should be replaced with factory method.
18
18
  class ReplaceComplexCreationWithFactoryMethodReview < Review
19
19
  def url
@@ -21,7 +21,7 @@ module RailsBestPractices
21
21
  end
22
22
 
23
23
  def interesting_nodes
24
- [:defn]
24
+ [:def]
25
25
  end
26
26
 
27
27
  def interesting_files
@@ -30,21 +30,23 @@ module RailsBestPractices
30
30
 
31
31
  def initialize(options = {})
32
32
  super()
33
- @attrasgn_count = options['attribute_assignment_count'] || 2
33
+ @assigns_count = options['attribute_assignment_count'] || 2
34
34
  end
35
35
 
36
- # check method define node to see if there are multiple attribute assignments, more than @attrasgn_count, on one local variable or instance variable before save.
36
+ # check method define node to see if there are multiple assignments, more than @assigns_count, on one variable before save.
37
37
  #
38
38
  # it wll check every attrasgn nodes in method define node,
39
- # if there are multiple attrasgn nodes who have the same subject,
40
- # and the subject is a local variable or an instance variable,
41
- # and after them, there is a call node with message :save or :save!,
39
+ # if there are multiple assign nodes who have the same subject,
40
+ # and the subject is a variable,
41
+ # and after them, there is a call node with message "save" or "save!",
42
42
  # then these attribute assignments are complex creation, should be replaced with factory method.
43
- def start_defn(node)
43
+ def start_def(node)
44
44
  node.recursive_children do |child_node|
45
- case child_node.node_type
46
- when :attrasgn
47
- remember_variable_use_count(child_node)
45
+ case child_node.sexp_type
46
+ when :assign
47
+ if :"." == child_node.subject[2]
48
+ remember_variable_use_count(child_node)
49
+ end
48
50
  when :call
49
51
  check_variable_save(child_node)
50
52
  else
@@ -54,14 +56,14 @@ module RailsBestPractices
54
56
  end
55
57
 
56
58
  private
57
- # check the call node to see if it is with message :save or :save!,
58
- # and the count attribute assignment on the subject of the call node is greater than @attrasgn_count defined,
59
+ # check the call node to see if it is with message "save" or "save!",
60
+ # and the count attribute assignment on the subject of the call node is greater than @assign_count defined,
59
61
  # then it is a complex creation, should be replaced with factory method.
60
62
  def check_variable_save(node)
61
- if [:save, :save!].include? node.message
62
- variable = node.subject
63
- if variable_use_count[variable].to_i > @attrasgn_count
64
- add_error "replace complex creation with factory method (#{variable} attribute_assignment_count > #{@attrasgn_count})"
63
+ if ["save", "save!"].include? node.message.to_s
64
+ variable = node.subject.to_s
65
+ if variable_use_count[variable].to_i > @assigns_count
66
+ add_error "replace complex creation with factory method (#{variable} attribute_assignment_count > #{@assigns_count})"
65
67
  end
66
68
  end
67
69
  end