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