rails_best_practices 0.6.6 → 0.6.7
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/Gemfile +0 -1
- data/README.md +28 -24
- data/Rakefile +0 -8
- data/install_supported_rubies.sh +2 -3
- data/lib/rails_best_practices.rb +8 -7
- data/lib/rails_best_practices/core.rb +1 -0
- data/lib/rails_best_practices/core/check.rb +68 -0
- data/lib/rails_best_practices/core/checking_visitor.rb +18 -15
- data/lib/rails_best_practices/core/runner.rb +22 -12
- data/lib/rails_best_practices/core/visitable_sexp.rb +6 -2
- data/lib/rails_best_practices/prepares.rb +11 -0
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +33 -0
- data/lib/rails_best_practices/prepares/model_prepare.rb +60 -0
- data/lib/rails_best_practices/reviews.rb +23 -0
- data/lib/rails_best_practices/{checks/add_model_virtual_attribute_check.rb → reviews/add_model_virtual_attribute_review.rb} +6 -9
- data/lib/rails_best_practices/{checks/always_add_db_index_check.rb → reviews/always_add_db_index_review.rb} +9 -12
- data/lib/rails_best_practices/{checks/dry_bundler_in_capistrano_check.rb → reviews/dry_bundler_in_capistrano_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/isolate_seed_data_check.rb → reviews/isolate_seed_data_review.rb} +11 -14
- data/lib/rails_best_practices/{checks/keep_finders_on_their_own_model_check.rb → reviews/keep_finders_on_their_own_model_review.rb} +7 -10
- data/lib/rails_best_practices/{checks/law_of_demeter_check.rb → reviews/law_of_demeter_review.rb} +10 -14
- data/lib/rails_best_practices/{checks/move_code_into_controller_check.rb → reviews/move_code_into_controller_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/move_code_into_helper_check.rb → reviews/move_code_into_helper_review.rb} +7 -10
- data/lib/rails_best_practices/{checks/move_code_into_model_check.rb → reviews/move_code_into_model_review.rb} +7 -10
- data/lib/rails_best_practices/{checks/move_finder_to_named_scope_check.rb → reviews/move_finder_to_named_scope_review.rb} +7 -10
- data/lib/rails_best_practices/{checks/move_model_logic_into_model_check.rb → reviews/move_model_logic_into_model_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/needless_deep_nesting_check.rb → reviews/needless_deep_nesting_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/not_use_default_route_check.rb → reviews/not_use_default_route_review.rb} +7 -10
- data/lib/rails_best_practices/{checks/overuse_route_customizations_check.rb → reviews/overuse_route_customizations_review.rb} +10 -13
- data/lib/rails_best_practices/{checks/replace_complex_creation_with_factory_method_check.rb → reviews/replace_complex_creation_with_factory_method_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/replace_instance_variable_with_local_variable_check.rb → reviews/replace_instance_variable_with_local_variable_review.rb} +7 -10
- data/lib/rails_best_practices/reviews/review.rb +92 -0
- data/lib/rails_best_practices/{checks/use_before_filter_check.rb → reviews/use_before_filter_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/use_model_association_check.rb → reviews/use_model_association_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/use_observer_check.rb → reviews/use_observer_review.rb} +14 -41
- data/lib/rails_best_practices/{checks/use_query_attribute_check.rb → reviews/use_query_attribute_review.rb} +20 -16
- data/lib/rails_best_practices/{checks/use_say_with_time_in_migrations_check.rb → reviews/use_say_with_time_in_migrations_review.rb} +8 -11
- data/lib/rails_best_practices/{checks/use_scope_access_check.rb → reviews/use_scope_access_review.rb} +8 -11
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +3 -2
- data/rails_best_practices.yml +22 -22
- data/rake_rubies.sh +3 -2
- data/spec/rails_best_practices/core/check_spec.rb +41 -0
- data/spec/rails_best_practices/core/checking_visitor_spec.rb +78 -0
- data/spec/rails_best_practices/core/visitable_sexp_spec.rb +39 -36
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +14 -0
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +22 -0
- data/spec/rails_best_practices/{checks/add_model_virtual_attribute_check_spec.rb → reviews/add_model_virtual_attribute_review_spec.rb} +17 -25
- data/spec/rails_best_practices/{checks/always_add_db_index_check_spec.rb → reviews/always_add_db_index_review_spec.rb} +28 -41
- data/spec/rails_best_practices/{checks/dry_bundler_in_capistrano_check_spec.rb → reviews/dry_bundler_in_capistrano_review_spec.rb} +7 -11
- data/spec/rails_best_practices/{checks/isolate_seed_data_check_spec.rb → reviews/isolate_seed_data_review_spec.rb} +13 -20
- data/spec/rails_best_practices/{checks/keep_finders_on_their_own_model_check_spec.rb → reviews/keep_finders_on_their_own_model_review_spec.rb} +16 -24
- data/spec/rails_best_practices/{checks/law_of_demeter_check_spec.rb → reviews/law_of_demeter_review_spec.rb} +24 -26
- data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +29 -0
- data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +24 -0
- data/spec/rails_best_practices/{checks/move_code_into_model_check_spec.rb → reviews/move_code_into_model_review_spec.rb} +12 -18
- data/spec/rails_best_practices/{checks/move_finder_to_named_scope_check_spec.rb → reviews/move_finder_to_named_scope_review_spec.rb} +12 -16
- data/spec/rails_best_practices/{checks/move_model_logic_into_model_check_spec.rb → reviews/move_model_logic_into_model_review_spec.rb} +7 -11
- data/spec/rails_best_practices/{checks/needless_deep_nesting_check_spec.rb → reviews/needless_deep_nesting_review_spec.rb} +26 -37
- data/spec/rails_best_practices/{checks/not_use_default_route_check_spec.rb → reviews/not_use_default_route_review_spec.rb} +13 -19
- data/spec/rails_best_practices/{checks/overuse_route_customizations_check_spec.rb → reviews/overuse_route_customizations_review_spec.rb} +27 -39
- data/spec/rails_best_practices/{checks/replace_complex_creation_with_factory_method_check_spec.rb → reviews/replace_complex_creation_with_factory_method_review_spec.rb} +10 -15
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +31 -0
- data/spec/rails_best_practices/reviews/review_spec.rb +11 -0
- data/spec/rails_best_practices/{checks/use_before_filter_check_spec.rb → reviews/use_before_filter_review_spec.rb} +11 -17
- data/spec/rails_best_practices/{checks/use_model_association_check_spec.rb → reviews/use_model_association_review_spec.rb} +12 -18
- data/spec/rails_best_practices/{checks/use_observer_check_spec.rb → reviews/use_observer_review_spec.rb} +28 -29
- data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +190 -0
- data/spec/rails_best_practices/{checks/use_say_with_time_in_migrations_check_spec.rb → reviews/use_say_with_time_in_migrations_review_spec.rb} +14 -23
- data/spec/rails_best_practices/{checks/use_scope_access_check_spec.rb → reviews/use_scope_access_review_spec.rb} +28 -37
- data/spec/rails_best_practices_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- metadata +128 -102
- data/lib/rails_best_practices/checks.rb +0 -23
- data/lib/rails_best_practices/checks/check.rb +0 -203
- data/spec/rails_best_practices/checks/check_spec.rb +0 -57
- data/spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb +0 -33
- data/spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb +0 -28
- data/spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb +0 -36
- data/spec/rails_best_practices/checks/use_query_attribute_check_spec.rb +0 -192
@@ -1,21 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
6
|
-
#
|
5
|
+
module Reviews
|
6
|
+
# Review a controller file to make sure to use before_filter to remove duplicated first code line in different action.
|
7
7
|
#
|
8
8
|
# See the best practice detailed here http://rails-bestpractices.com/posts/22-use-before_filter.
|
9
9
|
#
|
10
10
|
# Implementation:
|
11
11
|
#
|
12
|
-
# Prepare process:
|
13
|
-
# none
|
14
|
-
#
|
15
12
|
# Review process:
|
16
13
|
# check all first code line in method definitions (actions),
|
17
14
|
# if they are duplicated, then they should be moved to before_filter.
|
18
|
-
class
|
15
|
+
class UseBeforeFilterReview < Review
|
19
16
|
|
20
17
|
PROTECTED_PRIVATE_CALLS = [[:call, nil, :protected, [:arglist]], [:call, nil, :private, [:arglist]]]
|
21
18
|
|
@@ -23,15 +20,15 @@ module RailsBestPractices
|
|
23
20
|
"http://rails-bestpractices.com/posts/22-use-before_filter"
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
23
|
+
def interesting_nodes
|
27
24
|
[:class]
|
28
25
|
end
|
29
26
|
|
30
|
-
def
|
27
|
+
def interesting_files
|
31
28
|
CONTROLLER_FILES
|
32
29
|
end
|
33
30
|
|
34
|
-
# check class define node to see if there are method define nodes whose first code line are duplicated
|
31
|
+
# check class define node to see if there are method define nodes whose first code line are duplicated.
|
35
32
|
#
|
36
33
|
# it will check every defn nodes in the class node until protected or private identification,
|
37
34
|
# if there are defn nodes who have the same first code line, like
|
@@ -74,7 +71,7 @@ module RailsBestPractices
|
|
74
71
|
# )
|
75
72
|
#
|
76
73
|
# then these duplicated first code lines should be moved to before_filter.
|
77
|
-
def
|
74
|
+
def start_class(class_node)
|
78
75
|
@first_sentences = {}
|
79
76
|
|
80
77
|
class_node.body.children.each do |child_node|
|
@@ -1,37 +1,34 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
6
|
-
#
|
5
|
+
module Reviews
|
6
|
+
# review a controller file to make sure to use model association instead of foreign key id assignment.
|
7
7
|
#
|
8
8
|
# See the best practice details here http://rails-bestpractices.com/posts/2-use-model-association.
|
9
9
|
#
|
10
10
|
# Implementation:
|
11
11
|
#
|
12
|
-
# Prepare process:
|
13
|
-
# none
|
14
|
-
#
|
15
12
|
# Review process:
|
16
13
|
# check model define nodes in all controller files,
|
17
14
|
# if there is an attribute assignment node with message xxx_id=,
|
18
15
|
# and after it, there is a call node with message :save or :save!,
|
19
16
|
# and the subjects of attribute assignment node and call node are the same,
|
20
17
|
# then model association should be used instead of xxx_id assignment.
|
21
|
-
class
|
18
|
+
class UseModelAssociationReview < Review
|
22
19
|
def url
|
23
20
|
"http://rails-bestpractices.com/posts/2-use-model-association"
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
23
|
+
def interesting_nodes
|
27
24
|
[:defn]
|
28
25
|
end
|
29
26
|
|
30
|
-
def
|
27
|
+
def interesting_files
|
31
28
|
CONTROLLER_FILES
|
32
29
|
end
|
33
30
|
|
34
|
-
# check method define nodes to see if there are some attribute assignments that can use model association instead
|
31
|
+
# check method define nodes to see if there are some attribute assignments that can use model association instead.
|
35
32
|
#
|
36
33
|
# it will check attribute assignment node with message xxx_id=, and call node with message :save or :save!
|
37
34
|
#
|
@@ -40,7 +37,7 @@ module RailsBestPractices
|
|
40
37
|
# 2. after assignment, if there is a call node with message :save or :save!,
|
41
38
|
# and the subject of call node is one of the subject of attribute assignment node,
|
42
39
|
# then the attribute assignment should be replaced by using model association.
|
43
|
-
def
|
40
|
+
def start_defn(node)
|
44
41
|
@attrasgns = {}
|
45
42
|
node.recursive_children do |child|
|
46
43
|
case child.node_type
|
data/lib/rails_best_practices/{checks/use_observer_check.rb → reviews/use_observer_review.rb}
RENAMED
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
5
|
+
module Reviews
|
6
6
|
# Make sure to use observer (sorry we only check the mailer deliver now).
|
7
7
|
#
|
8
8
|
# See the best practice details here http://rails-bestpractices.com/posts/19-use-observer.
|
@@ -23,42 +23,25 @@ module RailsBestPractices
|
|
23
23
|
# if the method is a callback method,
|
24
24
|
# and there is a mailer deliver call,
|
25
25
|
# then the method should be replaced by using observer.
|
26
|
-
class
|
26
|
+
class UseObserverReview < Review
|
27
27
|
def url
|
28
28
|
"http://rails-bestpractices.com/posts/19-use-observer"
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
[:class]
|
33
|
-
end
|
34
|
-
|
35
|
-
def interesting_review_nodes
|
31
|
+
def interesting_nodes
|
36
32
|
[:defn, :call]
|
37
33
|
end
|
38
34
|
|
39
|
-
def
|
40
|
-
/#{MAILER_FILES}|#{MODEL_FILES}/
|
41
|
-
end
|
42
|
-
|
43
|
-
def interesting_review_files
|
35
|
+
def interesting_files
|
44
36
|
MODEL_FILES
|
45
37
|
end
|
46
38
|
|
47
39
|
def initialize
|
48
40
|
super
|
49
41
|
@callbacks = []
|
50
|
-
@mailer_names = []
|
51
42
|
end
|
52
43
|
|
53
|
-
# check
|
54
|
-
#
|
55
|
-
# if it is a subclass of ActionMailer::Base,
|
56
|
-
# then remember its class name.
|
57
|
-
def prepare_start_class(node)
|
58
|
-
remember_mailer_names(node)
|
59
|
-
end
|
60
|
-
|
61
|
-
# check a call node in review process.
|
44
|
+
# check a call node.
|
62
45
|
#
|
63
46
|
# if it is a callback definition, like
|
64
47
|
#
|
@@ -66,7 +49,7 @@ module RailsBestPractices
|
|
66
49
|
# before_destroy :send_destroy_notification
|
67
50
|
#
|
68
51
|
# then remember its callback methods (:send_create_notification).
|
69
|
-
def
|
52
|
+
def start_call(node)
|
70
53
|
remember_callback(node)
|
71
54
|
end
|
72
55
|
|
@@ -75,27 +58,13 @@ module RailsBestPractices
|
|
75
58
|
# if it is callback method,
|
76
59
|
# and there is a actionmailer deliver call in the method define node,
|
77
60
|
# then it should be replaced by using observer.
|
78
|
-
def
|
61
|
+
def start_defn(node)
|
79
62
|
if callback_method?(node) and deliver_mailer?(node)
|
80
63
|
add_error "use observer"
|
81
64
|
end
|
82
65
|
end
|
83
66
|
|
84
67
|
private
|
85
|
-
# check a class node, if its base class is ActionMailer::Base, like
|
86
|
-
#
|
87
|
-
# s(:class, :ProjectMailer,
|
88
|
-
# s(:colon2, s(:const, :ActionMailer), :Base),
|
89
|
-
# s(:scope)
|
90
|
-
# )
|
91
|
-
#
|
92
|
-
# then save the class name in @mailer_names
|
93
|
-
def remember_mailer_names(node)
|
94
|
-
if s(:colon2, s(:const, :ActionMailer), :Base) == node.base_class
|
95
|
-
@mailer_names << node.class_name.to_s
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
68
|
# check a call node, if it is a callback definition, such as after_create, before_create, like
|
100
69
|
#
|
101
70
|
# s(:call, nil, :after_create,
|
@@ -147,12 +116,16 @@ module RailsBestPractices
|
|
147
116
|
def deliver_mailer?(node)
|
148
117
|
node.grep_nodes(:node_type => :call) do |child_node|
|
149
118
|
# rails2 actionmailer deliver
|
150
|
-
return true if child_node.message.to_s =~ /^deliver_/ &&
|
119
|
+
return true if child_node.message.to_s =~ /^deliver_/ && mailer_names.include?(child_node.subject.to_s)
|
151
120
|
# rails3 actionmailer deliver
|
152
|
-
return true if :deliver == child_node.message &&
|
121
|
+
return true if :deliver == child_node.message && mailer_names.include?(child_node.subject.subject.to_s)
|
153
122
|
end
|
154
123
|
false
|
155
124
|
end
|
125
|
+
|
126
|
+
def mailer_names
|
127
|
+
@mailer_names ||= Prepares.mailer_names.collect(&:to_s)
|
128
|
+
end
|
156
129
|
end
|
157
130
|
end
|
158
131
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
5
|
+
module Reviews
|
6
6
|
# Make sure to use query attribute instead of nil?, blank? and present?.
|
7
7
|
#
|
8
8
|
# See the best practice details here http://rails-bestpractices.com/posts/56-use-query-attribute.
|
@@ -20,21 +20,19 @@ module RailsBestPractices
|
|
20
20
|
# and their messages of first call are not pluralize and not in any of the association names
|
21
21
|
# and their messages of second call are one of nil?, blank?, present?, or they are == ""
|
22
22
|
# then you can use query attribute instead.
|
23
|
-
class
|
23
|
+
class UseQueryAttributeReview < Review
|
24
24
|
|
25
25
|
QUERY_METHODS = [:nil?, :blank?, :present?]
|
26
26
|
|
27
|
-
prepare_model_associations
|
28
|
-
|
29
27
|
def url
|
30
28
|
"http://rails-bestpractices.com/posts/56-use-query-attribute"
|
31
29
|
end
|
32
30
|
|
33
|
-
def
|
31
|
+
def interesting_nodes
|
34
32
|
[:if]
|
35
33
|
end
|
36
34
|
|
37
|
-
# check if node to see whose conditional statement nodes contain nodes that can use query attribute instead
|
35
|
+
# check if node to see whose conditional statement nodes contain nodes that can use query attribute instead.
|
38
36
|
#
|
39
37
|
# it will check every call nodes in the if nodes. If the call node is
|
40
38
|
#
|
@@ -46,7 +44,7 @@ module RailsBestPractices
|
|
46
44
|
# the message is == and the argument is ""
|
47
45
|
#
|
48
46
|
# then the call node can use query attribute instead.
|
49
|
-
def
|
47
|
+
def start_if(node)
|
50
48
|
if node = query_attribute_node(node.conditional_statement)
|
51
49
|
subject_node = node.subject
|
52
50
|
add_error "use query attribute (#{subject_node.subject}.#{subject_node.message}?)", node.file, node.line
|
@@ -85,24 +83,30 @@ module RailsBestPractices
|
|
85
83
|
def possible_query_attribute?(node)
|
86
84
|
return false unless :call == node.subject.node_type
|
87
85
|
subject = node.subject.subject
|
86
|
+
return false unless subject
|
88
87
|
message = node.subject.message
|
89
88
|
|
90
|
-
[:arglist] == node.subject.arguments &&
|
91
|
-
(QUERY_METHODS.include?(node.message) || compare_with_empty_string?(node))
|
89
|
+
[:arglist] == node.subject.arguments && is_model?(subject) && !model_association?(subject, message) &&
|
90
|
+
!pluralize?(message.to_s) && (QUERY_METHODS.include?(node.message) || compare_with_empty_string?(node))
|
91
|
+
end
|
92
|
+
|
93
|
+
def is_model?(subject)
|
94
|
+
return false if :const == subject.node_type
|
95
|
+
class_name = subject.to_s(:remove_at => true).classify
|
96
|
+
!model_associations[class_name].nil?
|
92
97
|
end
|
93
98
|
|
94
|
-
# check if the subject and message is one of the model's
|
95
|
-
# the subject should match one of the class model name, and the message should
|
99
|
+
# check if the subject and message is one of the model's aassociation.
|
100
|
+
# the subject should match one of the class model name, and the message should match one of association name.
|
96
101
|
#
|
97
102
|
# subject, subject of call node, like
|
98
103
|
# s(:ivar, @user)
|
99
104
|
#
|
100
105
|
# message, message of call node, like
|
101
106
|
# :login
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
end
|
107
|
+
def model_association?(subject, message)
|
108
|
+
class_name = subject.to_s(:remove_at => true).classify
|
109
|
+
!model_associations[class_name][message.to_s].nil?
|
106
110
|
end
|
107
111
|
|
108
112
|
|
@@ -1,23 +1,20 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
6
|
-
#
|
5
|
+
module Reviews
|
6
|
+
# Review a migration file to make sure to use say or say_with_time for customized data changes to produce a more readable output.
|
7
7
|
#
|
8
8
|
# See the best practice detials here http://rails-bestpractices.com/posts/46-use-say-and-say_with_time-in-migrations-to-make-a-useful-migration-log.
|
9
9
|
#
|
10
10
|
# Implementation:
|
11
11
|
#
|
12
|
-
# Prepare process:
|
13
|
-
# none
|
14
|
-
#
|
15
12
|
# Review process:
|
16
13
|
# check class method define nodes (self.up or self.down).
|
17
14
|
# if there is a method call in the class method definition,
|
18
15
|
# and the message of method call is not say, say_with_time and default migration methods (such as add_column and create_table),
|
19
16
|
# then the method call should be wrapped by say or say_with_time.
|
20
|
-
class
|
17
|
+
class UseSayWithTimeInMigrationsReview < Review
|
21
18
|
|
22
19
|
DEFAULT_MIGRATION_METHODS = [:add_column, :add_index, :add_timestamps, :change_column, :change_column_default, :change_table, :create_table, :drop_table, :remove_column, :remove_index, :remove_timestamps, :rename_column, :rename_index, :rename_table]
|
23
20
|
WITH_SAY_METHODS = DEFAULT_MIGRATION_METHODS + [:say, :say_with_time]
|
@@ -26,15 +23,15 @@ module RailsBestPractices
|
|
26
23
|
"http://rails-bestpractices.com/posts/46-use-say-and-say_with_time-in-migrations-to-make-a-useful-migration-log"
|
27
24
|
end
|
28
25
|
|
29
|
-
def
|
26
|
+
def interesting_nodes
|
30
27
|
[:defs]
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
30
|
+
def interesting_files
|
34
31
|
MIGRATION_FILES
|
35
32
|
end
|
36
33
|
|
37
|
-
# check a class method define node to see if there are method calls that need to be wrapped by :say or :say_with_time
|
34
|
+
# check a class method define node to see if there are method calls that need to be wrapped by :say or :say_with_time.
|
38
35
|
#
|
39
36
|
# it will check the first block node,
|
40
37
|
# if any method call whose message is not default migration methods in the block node, like
|
@@ -67,7 +64,7 @@ module RailsBestPractices
|
|
67
64
|
# )
|
68
65
|
#
|
69
66
|
# then such method call should be wrapped by say or say_with_time
|
70
|
-
def
|
67
|
+
def start_defs(node)
|
71
68
|
block_node = node.grep_node(:node_type => :block)
|
72
69
|
block_node.children.each do |child_node|
|
73
70
|
if :iter == child_node.node_type
|
@@ -1,37 +1,34 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rails_best_practices/
|
2
|
+
require 'rails_best_practices/reviews/review'
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
|
-
module
|
6
|
-
#
|
5
|
+
module Reviews
|
6
|
+
# Review a controller to make sure to use scope access instead of manually checking current_user and redirect.
|
7
7
|
#
|
8
8
|
# See the best practice details here http://rails-bestpractices.com/posts/3-use-scope-access.
|
9
9
|
#
|
10
10
|
# Implementation:
|
11
11
|
#
|
12
|
-
# Prepare process:
|
13
|
-
# none
|
14
|
-
#
|
15
12
|
# Review process:
|
16
13
|
# check all if nodes to see
|
17
14
|
#
|
18
15
|
# if they are compared with current_user or current_user.id,
|
19
16
|
# and there is redirect_to method call in if block body,
|
20
17
|
# then it should be replaced by using scope access.
|
21
|
-
class
|
18
|
+
class UseScopeAccessReview < Review
|
22
19
|
def url
|
23
20
|
"http://rails-bestpractices.com/posts/3-use-scope-access"
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
23
|
+
def interesting_nodes
|
27
24
|
[:if]
|
28
25
|
end
|
29
26
|
|
30
|
-
def
|
27
|
+
def interesting_files
|
31
28
|
CONTROLLER_FILES
|
32
29
|
end
|
33
30
|
|
34
|
-
# check if node
|
31
|
+
# check if node.
|
35
32
|
#
|
36
33
|
# if it is a method call compared with current_user or current_user.id,
|
37
34
|
# and there is a redirect_to method call in the block body, like
|
@@ -42,7 +39,7 @@ module RailsBestPractices
|
|
42
39
|
# end
|
43
40
|
#
|
44
41
|
# then it should be replaced by using scope access.
|
45
|
-
def
|
42
|
+
def start_if(node)
|
46
43
|
add_error "use scope access" if current_user_redirect?(node)
|
47
44
|
end
|
48
45
|
|
@@ -21,7 +21,8 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_dependency("i18n")
|
22
22
|
s.add_dependency("activesupport")
|
23
23
|
|
24
|
-
s.add_development_dependency("
|
24
|
+
s.add_development_dependency("rake")
|
25
|
+
s.add_development_dependency("rspec", "~> 2.4.0")
|
25
26
|
s.add_development_dependency("watchr", "~> 0.6")
|
26
27
|
s.add_development_dependency("bundler", ">= 1.0.0")
|
27
28
|
|
@@ -35,7 +36,7 @@ Gem::Specification.new do |s|
|
|
35
36
|
|
36
37
|
rails_best_practices is a code metric tool to check the quality of rails codes.
|
37
38
|
|
38
|
-
I highly recommend you
|
39
|
+
I highly recommend you browse the Rails Best Practices website first.
|
39
40
|
|
40
41
|
http://rails-bestpractices.com
|
41
42
|
|
data/rails_best_practices.yml
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
MoveFinderToNamedScopeReview: { }
|
2
|
+
UseModelAssociationReview: { }
|
3
|
+
UseScopeAccessReview: { }
|
4
|
+
AddModelVirtualAttributeReview: { }
|
5
|
+
ReplaceComplexCreationWithFactoryMethodReview: { attribute_assignment_count: 2 }
|
6
|
+
MoveModelLogicIntoModelReview: { use_count: 4 }
|
7
|
+
OveruseRouteCustomizationsReview: { customize_count: 3 }
|
8
|
+
NeedlessDeepNestingReview: { nested_count: 2 }
|
9
|
+
NotUseDefaultRouteReview: { }
|
10
|
+
KeepFindersOnTheirOwnModelReview: { }
|
11
|
+
LawOfDemeterReview: { }
|
12
|
+
UseObserverReview: { }
|
13
|
+
IsolateSeedDataReview: { }
|
14
|
+
AlwaysAddDbIndexReview: { }
|
15
|
+
UseBeforeFilterReview: { }
|
16
|
+
MoveCodeIntoControllerReview: { }
|
17
|
+
MoveCodeIntoModelReview: { use_count: 2 }
|
18
|
+
MoveCodeIntoHelperReview: { array_count: 3 }
|
19
|
+
ReplaceInstanceVariableWithLocalVariableReview: { }
|
20
|
+
DryBundlerInCapistranoReview: { }
|
21
|
+
UseSayWithTimeInMigrationsReview: { }
|
22
|
+
UseQueryAttributeReview: { }
|