rails_best_practices 1.1.0 → 1.2.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.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/assets/result.html.erb +25 -2
- data/lib/rails_best_practices.rb +20 -9
- data/lib/rails_best_practices/core.rb +1 -0
- data/lib/rails_best_practices/core/check.rb +106 -25
- data/lib/rails_best_practices/core/controllers.rb +2 -1
- data/lib/rails_best_practices/core/error.rb +3 -2
- data/lib/rails_best_practices/core/klasses.rb +34 -0
- data/lib/rails_best_practices/core/mailers.rb +2 -1
- data/lib/rails_best_practices/core/methods.rb +113 -9
- data/lib/rails_best_practices/core/model_associations.rb +17 -0
- data/lib/rails_best_practices/core/model_attributes.rb +16 -0
- data/lib/rails_best_practices/core/models.rb +3 -2
- data/lib/rails_best_practices/core/nil.rb +9 -1
- data/lib/rails_best_practices/core/runner.rb +65 -26
- data/lib/rails_best_practices/core_ext/sexp.rb +57 -0
- data/lib/rails_best_practices/prepares.rb +12 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +13 -8
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/model_prepare.rb +44 -16
- data/lib/rails_best_practices/reviews.rb +1 -0
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +5 -2
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +77 -0
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +2 -2
- data/lib/rails_best_practices/reviews/review.rb +1 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.yml +1 -0
- data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +11 -0
- data/spec/rails_best_practices/core/check_spec.rb +22 -0
- data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
- data/spec/rails_best_practices/core/error_spec.rb +1 -1
- data/spec/rails_best_practices/core/klasses_spec.rb +12 -0
- data/spec/rails_best_practices/core/mailers_spec.rb +5 -0
- data/spec/rails_best_practices/core/methods_spec.rb +26 -4
- data/spec/rails_best_practices/core/models_spec.rb +2 -2
- data/spec/rails_best_practices/core/runner_spec.rb +13 -0
- data/spec/rails_best_practices/core_ext/sexp_spec.rb +26 -2
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +72 -60
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +1 -1
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +150 -59
- data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +20 -3
- data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +14 -0
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +387 -0
- metadata +15 -3
@@ -1,21 +1,38 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module RailsBestPractices
|
3
3
|
module Core
|
4
|
+
# Model associations container.
|
4
5
|
class ModelAssociations
|
5
6
|
def initialize
|
6
7
|
@associations = {}
|
7
8
|
end
|
8
9
|
|
10
|
+
# Add a model association.
|
11
|
+
#
|
12
|
+
# @param [String] model name
|
13
|
+
# @param [String] association name
|
14
|
+
# @param [String] association meta, has_many, has_one, belongs_to and has_and_belongs_to_many
|
15
|
+
# @param [String] association class name
|
9
16
|
def add_association(model_name, association_name, association_meta, association_class=nil)
|
10
17
|
@associations[model_name] ||= {}
|
11
18
|
@associations[model_name][association_name] = {"meta" => association_meta, "class_name" => association_class || association_name.classify}
|
12
19
|
end
|
13
20
|
|
21
|
+
# Get a model association.
|
22
|
+
#
|
23
|
+
# @param [String] model name
|
24
|
+
# @param [String] association name
|
25
|
+
# @return [Hash] {"meta" => association_meta, "class_name" => association_class}
|
14
26
|
def get_association(model_name, association_name)
|
15
27
|
associations = @associations[model_name]
|
16
28
|
associations and associations[association_name]
|
17
29
|
end
|
18
30
|
|
31
|
+
# If it is a model's association.
|
32
|
+
#
|
33
|
+
# @param [String] model name
|
34
|
+
# @param [String] association name
|
35
|
+
# @return [Boolean] true if it is the model's association
|
19
36
|
def is_association?(model_name, association_name)
|
20
37
|
associations = @associations[model_name]
|
21
38
|
associations && associations[association_name]
|
@@ -1,21 +1,37 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module RailsBestPractices
|
3
3
|
module Core
|
4
|
+
# Model attributes container.
|
4
5
|
class ModelAttributes
|
5
6
|
def initialize
|
6
7
|
@attributes = {}
|
7
8
|
end
|
8
9
|
|
10
|
+
# Add a model attribute.
|
11
|
+
#
|
12
|
+
# @param [String] model name
|
13
|
+
# @param [String] attribute name
|
14
|
+
# @param [String] attribute type
|
9
15
|
def add_attribute(model_name, attribute_name, attribute_type)
|
10
16
|
@attributes[model_name] ||= {}
|
11
17
|
@attributes[model_name][attribute_name] = attribute_type
|
12
18
|
end
|
13
19
|
|
20
|
+
# Get attribute type.
|
21
|
+
#
|
22
|
+
# @param [String] model name
|
23
|
+
# @param [String] attribute name
|
24
|
+
# @return [String] attribute type
|
14
25
|
def get_attribute_type(model_name, attribute_name)
|
15
26
|
@attributes[model_name] ||= {}
|
16
27
|
@attributes[model_name][attribute_name]
|
17
28
|
end
|
18
29
|
|
30
|
+
# If it is a model's attribute.
|
31
|
+
#
|
32
|
+
# @param [String] model name
|
33
|
+
# @param [String] attribute name
|
34
|
+
# @return [Boolean] true if it is the model's attribute
|
19
35
|
def is_attribute?(model_name, attribute_name)
|
20
36
|
@attributes[model_name] ||= {}
|
21
37
|
!!@attributes[model_name][attribute_name]
|
@@ -1,16 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module RailsBestPractices
|
3
3
|
module Core
|
4
|
+
# Fake nil.
|
4
5
|
class Nil
|
6
|
+
# hash_size is 0.
|
5
7
|
def hash_size
|
6
8
|
0
|
7
9
|
end
|
8
10
|
|
11
|
+
# array_size is 0.
|
12
|
+
def array_size
|
13
|
+
0
|
14
|
+
end
|
15
|
+
|
16
|
+
# return self for to_s.
|
9
17
|
def to_s
|
10
18
|
self
|
11
19
|
end
|
12
20
|
|
13
|
-
# return self
|
21
|
+
# return self.
|
14
22
|
def method_missing(method_sym, *arguments, &block)
|
15
23
|
self
|
16
24
|
end
|
@@ -38,9 +38,10 @@ module RailsBestPractices
|
|
38
38
|
custom_config = File.join(Runner.base_path, 'config/rails_best_practices.yml')
|
39
39
|
@config = File.exists?(custom_config) ? custom_config : RailsBestPractices::DEFAULT_CONFIG
|
40
40
|
|
41
|
+
lexicals = Array(options[:lexicals])
|
41
42
|
prepares = Array(options[:prepares])
|
42
43
|
reviews = Array(options[:reviews])
|
43
|
-
@lexicals = load_lexicals
|
44
|
+
@lexicals = lexicals.empty? ? load_lexicals : lexicals
|
44
45
|
@prepares = prepares.empty? ? load_prepares : prepares
|
45
46
|
@reviews = reviews.empty? ? load_reviews : reviews
|
46
47
|
|
@@ -64,28 +65,48 @@ module RailsBestPractices
|
|
64
65
|
#
|
65
66
|
# @param [String] filename
|
66
67
|
def lexical_file(filename)
|
67
|
-
lexical(filename,
|
68
|
+
lexical(filename, read_file(filename))
|
68
69
|
end
|
69
70
|
|
70
|
-
#
|
71
|
-
# the file may be a ruby, erb or haml file.
|
71
|
+
# parepare a file's content with filename.
|
72
72
|
#
|
73
|
-
#
|
74
|
-
# content
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
73
|
+
# @param [String] filename name of the file
|
74
|
+
# @param [String] content content of the file
|
75
|
+
def prepare(filename, content)
|
76
|
+
puts filename if @debug
|
77
|
+
node = parse_ruby(filename, content)
|
78
|
+
if node
|
79
|
+
node.file = filename
|
80
|
+
node.prepare(@checker)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# parapare the file.
|
85
|
+
#
|
86
|
+
# @param [String] filename
|
87
|
+
def prepare_file(filename)
|
88
|
+
prepare(filename, read_file(filename))
|
89
|
+
end
|
90
|
+
|
91
|
+
# review a file's content with filename.
|
92
|
+
#
|
93
|
+
# @param [String] filename name of the file
|
94
|
+
# @param [String] content content of the file
|
95
|
+
def review(filename, content)
|
96
|
+
puts filename if @debug
|
97
|
+
content = parse_erb_or_haml(filename, content)
|
98
|
+
node = parse_ruby(filename, content)
|
99
|
+
if node
|
100
|
+
node.file = filename
|
101
|
+
node.review(@checker)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# review the file.
|
106
|
+
#
|
107
|
+
# @param [String] filename
|
108
|
+
def review_file(filename)
|
109
|
+
review(filename, read_file(filename))
|
89
110
|
end
|
90
111
|
|
91
112
|
# get all errors from lexicals and reviews.
|
@@ -95,11 +116,21 @@ module RailsBestPractices
|
|
95
116
|
(@reviews + @lexicals).collect {|check| check.errors}.flatten
|
96
117
|
end
|
97
118
|
|
119
|
+
# provide a handler after all files reviewed.
|
120
|
+
def on_complete
|
121
|
+
filename = "rails_best_practices.complete"
|
122
|
+
content = "class RailsBestPractices::Complete; end"
|
123
|
+
node = parse_ruby(filename, content)
|
124
|
+
node.file = filename
|
125
|
+
node.review(@checker)
|
126
|
+
end
|
127
|
+
|
98
128
|
private
|
99
129
|
# parse ruby code.
|
100
130
|
#
|
101
|
-
#
|
102
|
-
|
131
|
+
# @param [String] filename is the filename of ruby file.
|
132
|
+
# @param [String] content is the source code of ruby file.
|
133
|
+
def parse_ruby(filename, content)
|
103
134
|
begin
|
104
135
|
Sexp.from_array(Ripper::SexpBuilder.new(content).parse)
|
105
136
|
rescue Exception => e
|
@@ -115,8 +146,8 @@ module RailsBestPractices
|
|
115
146
|
|
116
147
|
# parse erb or html code.
|
117
148
|
#
|
118
|
-
# filename is the filename of the erb or haml code.
|
119
|
-
# content is the source code of erb or haml file.
|
149
|
+
# @param [String] filename is the filename of the erb or haml code.
|
150
|
+
# @param [String] content is the source code of erb or haml file.
|
120
151
|
def parse_erb_or_haml(filename, content)
|
121
152
|
if filename =~ /.*\.erb|.*\.rhtml$/
|
122
153
|
content = Erubis::Eruby.new(content).src
|
@@ -171,12 +202,12 @@ module RailsBestPractices
|
|
171
202
|
# load all plugin reviews.
|
172
203
|
def load_plugin_reviews
|
173
204
|
begin
|
174
|
-
plugins = "lib/rails_best_practices/plugins/reviews"
|
205
|
+
plugins = "#{Runner.base_path}lib/rails_best_practices/plugins/reviews"
|
175
206
|
if File.directory?(plugins)
|
176
207
|
Dir[File.expand_path(File.join(plugins, "*.rb"))].each do |review|
|
177
208
|
require review
|
178
209
|
end
|
179
|
-
if RailsBestPractices.constants.include? :Plugins
|
210
|
+
if RailsBestPractices.constants.map(&:to_sym).include? :Plugins
|
180
211
|
RailsBestPractices::Plugins::Reviews.constants.each do |review|
|
181
212
|
@reviews << RailsBestPractices::Plugins::Reviews.const_get(review).new
|
182
213
|
end
|
@@ -189,6 +220,14 @@ module RailsBestPractices
|
|
189
220
|
def checks_from_config
|
190
221
|
@checks ||= YAML.load_file @config
|
191
222
|
end
|
223
|
+
|
224
|
+
# read the file content.
|
225
|
+
#
|
226
|
+
# @param [String] filename
|
227
|
+
# @return [String] file conent
|
228
|
+
def read_file(filename)
|
229
|
+
File.open(filename, "r:UTF-8") { |f| f.read }
|
230
|
+
end
|
192
231
|
end
|
193
232
|
end
|
194
233
|
end
|
@@ -593,6 +593,39 @@ class Sexp
|
|
593
593
|
end
|
594
594
|
end
|
595
595
|
|
596
|
+
# Get the hash values.
|
597
|
+
#
|
598
|
+
# s(:hash,
|
599
|
+
# s(:assoclist_from_args,
|
600
|
+
# s(
|
601
|
+
# s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))),
|
602
|
+
# s(:assoc_new, s(:@label, "last_name:", s(1, 24)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36)))))
|
603
|
+
# )
|
604
|
+
# )
|
605
|
+
# )
|
606
|
+
# => [
|
607
|
+
# s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14)))),
|
608
|
+
# s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36))))
|
609
|
+
# ]
|
610
|
+
#
|
611
|
+
# @return [Array] hash values
|
612
|
+
def hash_values
|
613
|
+
pair_nodes = case sexp_type
|
614
|
+
when :bare_assoc_hash
|
615
|
+
self[1]
|
616
|
+
when :hash
|
617
|
+
self[1][1]
|
618
|
+
else
|
619
|
+
end
|
620
|
+
if pair_nodes
|
621
|
+
values = []
|
622
|
+
pair_nodes.size.times do |i|
|
623
|
+
values << pair_nodes[i][2]
|
624
|
+
end
|
625
|
+
values
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
596
629
|
# Get the array size.
|
597
630
|
#
|
598
631
|
# s(:array,
|
@@ -624,6 +657,30 @@ class Sexp
|
|
624
657
|
end
|
625
658
|
end
|
626
659
|
|
660
|
+
# Get the array values.
|
661
|
+
#
|
662
|
+
# s(:array,
|
663
|
+
# s(:args_add,
|
664
|
+
# s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2))))),
|
665
|
+
# s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
|
666
|
+
# )
|
667
|
+
# )
|
668
|
+
# => [
|
669
|
+
# s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2)))),
|
670
|
+
# s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
|
671
|
+
# ]
|
672
|
+
#
|
673
|
+
# @return [Array] array values
|
674
|
+
def array_values
|
675
|
+
if :array == sexp_type
|
676
|
+
if nil == self[1]
|
677
|
+
[]
|
678
|
+
else
|
679
|
+
arguments.all
|
680
|
+
end
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
627
684
|
# To object.
|
628
685
|
#
|
629
686
|
# s(:array,
|
@@ -9,6 +9,10 @@ module RailsBestPractices
|
|
9
9
|
class <<self
|
10
10
|
attr_writer :models, :model_associations, :model_attributes, :mailers
|
11
11
|
|
12
|
+
def klasses
|
13
|
+
models + mailers + controllers
|
14
|
+
end
|
15
|
+
|
12
16
|
def models
|
13
17
|
@models ||= Core::Models.new
|
14
18
|
end
|
@@ -21,6 +25,10 @@ module RailsBestPractices
|
|
21
25
|
@model_attributes ||= Core::ModelAttributes.new
|
22
26
|
end
|
23
27
|
|
28
|
+
def model_methods
|
29
|
+
@model_methods ||= Core::Methods.new
|
30
|
+
end
|
31
|
+
|
24
32
|
def mailers
|
25
33
|
@mailers ||= Core::Mailers.new
|
26
34
|
end
|
@@ -33,8 +41,11 @@ module RailsBestPractices
|
|
33
41
|
@controller_methods ||= Core::Methods.new
|
34
42
|
end
|
35
43
|
|
44
|
+
# Clear all prepare objects.
|
36
45
|
def clear
|
37
|
-
|
46
|
+
instance_variables.each do |instance_variable|
|
47
|
+
instance_variable_set(instance_variable, nil)
|
48
|
+
end
|
38
49
|
end
|
39
50
|
end
|
40
51
|
end
|
@@ -5,7 +5,8 @@ module RailsBestPractices
|
|
5
5
|
module Prepares
|
6
6
|
# Remember controllers and controller methods
|
7
7
|
class ControllerPrepare < Core::Check
|
8
|
-
include Core::Check::
|
8
|
+
include Core::Check::Klassable
|
9
|
+
include Core::Check::Accessable
|
9
10
|
|
10
11
|
DEFAULT_ACTIONS = %w(index show new create edit update destroy)
|
11
12
|
|
@@ -26,9 +27,8 @@ module RailsBestPractices
|
|
26
27
|
# check class node to remember the class name.
|
27
28
|
# also check if the controller is inherit from InheritedResources::Base.
|
28
29
|
def start_class(node)
|
29
|
-
@
|
30
|
-
|
31
|
-
if "InheritedResources::Base" == node.base_class.to_s
|
30
|
+
@controllers << @klass
|
31
|
+
if "InheritedResources::Base" == current_extend_class_name
|
32
32
|
@inherited_resources = true
|
33
33
|
@actions = DEFAULT_ACTIONS
|
34
34
|
end
|
@@ -38,7 +38,7 @@ module RailsBestPractices
|
|
38
38
|
def end_class(node)
|
39
39
|
if @inherited_resources
|
40
40
|
@actions.each do |action|
|
41
|
-
@methods.add_method(
|
41
|
+
@methods.add_method(current_class_name, action)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -62,12 +62,17 @@ module RailsBestPractices
|
|
62
62
|
#
|
63
63
|
# the remembered methods (@methods) are like
|
64
64
|
# {
|
65
|
-
# "
|
66
|
-
#
|
65
|
+
# "PostsController" => {
|
66
|
+
# "save" => {"file" => "app/controllers/posts_controller.rb", "line" => 10, "unused" => false},
|
67
|
+
# "find" => {"file" => "app/controllers/posts_controller.rb", "line" => 10, "unused" => false}
|
68
|
+
# },
|
69
|
+
# "CommentsController" => {
|
70
|
+
# "create" => {"file" => "app/controllers/comments_controller.rb", "line" => 10, "unused" => false},
|
71
|
+
# }
|
67
72
|
# }
|
68
73
|
def start_def(node)
|
69
74
|
method_name = node.method_name.to_s
|
70
|
-
@methods.add_method(
|
75
|
+
@methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
|
71
76
|
end
|
72
77
|
end
|
73
78
|
end
|
@@ -5,7 +5,7 @@ module RailsBestPractices
|
|
5
5
|
module Prepares
|
6
6
|
# Remember the mailer names.
|
7
7
|
class MailerPrepare < Core::Check
|
8
|
-
include Core::Check::
|
8
|
+
include Core::Check::Klassable
|
9
9
|
|
10
10
|
def interesting_nodes
|
11
11
|
[:class, :module]
|
@@ -24,8 +24,8 @@ module RailsBestPractices
|
|
24
24
|
# if it is a subclass of ActionMailer::Base,
|
25
25
|
# then remember its class name.
|
26
26
|
def start_class(node)
|
27
|
-
if "ActionMailer::Base" ==
|
28
|
-
@mailers <<
|
27
|
+
if "ActionMailer::Base" == current_extend_class_name
|
28
|
+
@mailers << @klass
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -5,12 +5,13 @@ module RailsBestPractices
|
|
5
5
|
module Prepares
|
6
6
|
# Remember models and model associations.
|
7
7
|
class ModelPrepare < Core::Check
|
8
|
-
include Core::Check::
|
8
|
+
include Core::Check::Klassable
|
9
|
+
include Core::Check::Accessable
|
9
10
|
|
10
11
|
ASSOCIATION_METHODS = %w(belongs_to has_one has_many has_and_belongs_to_many)
|
11
12
|
|
12
13
|
def interesting_nodes
|
13
|
-
[:class, :command, :
|
14
|
+
[:module, :class, :def, :command, :var_ref]
|
14
15
|
end
|
15
16
|
|
16
17
|
def interesting_files
|
@@ -20,15 +21,36 @@ module RailsBestPractices
|
|
20
21
|
def initialize
|
21
22
|
@models = Prepares.models
|
22
23
|
@model_associations = Prepares.model_associations
|
24
|
+
@methods = Prepares.model_methods
|
23
25
|
end
|
24
26
|
|
25
27
|
# check class node to remember the last class name.
|
26
28
|
def start_class(node)
|
27
|
-
|
28
|
-
|
29
|
+
if "ActionMailer::Base" != current_extend_class_name
|
30
|
+
@models << @klass
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# check ref node to remember all methods.
|
35
|
+
#
|
36
|
+
# the remembered methods (@methods) are like
|
37
|
+
# {
|
38
|
+
# "Post" => {
|
39
|
+
# "save" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false},
|
40
|
+
# "find" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false}
|
41
|
+
# },
|
42
|
+
# "Comment" => {
|
43
|
+
# "create" => {"file" => "app/models/comment.rb", "line" => 10, "unused" => false, "unused" => false},
|
44
|
+
# }
|
45
|
+
# }
|
46
|
+
def start_def(node)
|
47
|
+
if @klass && "ActionMailer::Base" != current_extend_class_name
|
48
|
+
method_name = node.method_name.to_s
|
49
|
+
@methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
|
50
|
+
end
|
29
51
|
end
|
30
52
|
|
31
|
-
# check command node to remember all assoications.
|
53
|
+
# check command node to remember all assoications or named_scope/scope methods.
|
32
54
|
#
|
33
55
|
# the remembered association names (@associations) are like
|
34
56
|
# {
|
@@ -40,20 +62,26 @@ module RailsBestPractices
|
|
40
62
|
# }
|
41
63
|
# }
|
42
64
|
def start_command(node)
|
43
|
-
|
65
|
+
if %w(named_scope scope).include? node.message.to_s
|
66
|
+
method_name = node.arguments.all[0].to_s
|
67
|
+
@methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
|
68
|
+
elsif ASSOCIATION_METHODS.include? node.message.to_s
|
69
|
+
remember_association(node)
|
70
|
+
end
|
44
71
|
end
|
45
72
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
73
|
+
private
|
74
|
+
# remember associations, with class to association names.
|
75
|
+
def remember_association(node)
|
76
|
+
association_meta = node.message.to_s
|
77
|
+
association_name = node.arguments.all[0].to_s
|
78
|
+
arguments_node = node.arguments.all[1]
|
79
|
+
if arguments_node && :bare_assoc_hash == arguments_node.sexp_type
|
80
|
+
association_class = arguments_node.hash_value("class_name").to_s
|
81
|
+
end
|
82
|
+
association_class ||= association_name.classify
|
83
|
+
@model_associations.add_association(current_class_name, association_name, association_meta, association_class)
|
53
84
|
end
|
54
|
-
association_class ||= association_name.classify
|
55
|
-
@model_associations.add_association(@class_name, association_name, association_meta, association_class)
|
56
|
-
end
|
57
85
|
end
|
58
86
|
end
|
59
87
|
end
|