rails_best_practices 1.19.0 → 1.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Guardfile +2 -2
- data/Rakefile +8 -8
- data/bin/rails_best_practices +1 -1
- data/lib/rails_best_practices/analyzer.rb +45 -45
- data/lib/rails_best_practices/command.rb +40 -40
- data/lib/rails_best_practices/core/check.rb +15 -15
- data/lib/rails_best_practices/core/klasses.rb +1 -1
- data/lib/rails_best_practices/core/methods.rb +7 -7
- data/lib/rails_best_practices/core/model_associations.rb +3 -3
- data/lib/rails_best_practices/core/modules.rb +1 -1
- data/lib/rails_best_practices/core/routes.rb +2 -2
- data/lib/rails_best_practices/core/runner.rb +3 -3
- data/lib/rails_best_practices/core_ext/erubis.rb +4 -4
- data/lib/rails_best_practices/lexicals/remove_tab_check.rb +2 -2
- data/lib/rails_best_practices/lexicals/remove_trailing_whitespace_check.rb +2 -2
- data/lib/rails_best_practices/prepares/config_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +8 -8
- data/lib/rails_best_practices/prepares/helper_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/initializer_prepare.rb +4 -4
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +19 -19
- data/lib/rails_best_practices/prepares/route_prepare.rb +34 -34
- data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +2 -2
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +7 -7
- data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +1 -1
- data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +3 -3
- data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +3 -3
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +1 -1
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +6 -6
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +2 -2
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +4 -4
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +3 -3
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +2 -2
- data/lib/rails_best_practices/reviews/move_code_into_model_review.rb +1 -1
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +2 -2
- data/lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb +1 -1
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +4 -4
- data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +2 -2
- data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +4 -4
- data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +3 -3
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +2 -2
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +9 -9
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +3 -3
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +11 -11
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +1 -1
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +8 -7
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +2 -2
- data/lib/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review.rb +2 -2
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +22 -22
- data/lib/rails_best_practices/reviews/review.rb +2 -2
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +3 -3
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +4 -4
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +2 -2
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +2 -2
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +2 -2
- data/lib/rails_best_practices/reviews/use_observer_review.rb +3 -3
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +1 -1
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +3 -3
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +2 -2
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +5 -5
- data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +4 -4
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +24 -24
- data/spec/rails_best_practices/analyzer_spec.rb +43 -43
- data/spec/rails_best_practices/core/check_spec.rb +2 -2
- data/spec/rails_best_practices/core/checks_loader_spec.rb +4 -4
- data/spec/rails_best_practices/core/error_spec.rb +16 -16
- data/spec/rails_best_practices/core/except_methods_spec.rb +15 -15
- data/spec/rails_best_practices/core/gems_spec.rb +9 -9
- data/spec/rails_best_practices/core/klasses_spec.rb +17 -17
- data/spec/rails_best_practices/core/methods_spec.rb +28 -28
- data/spec/rails_best_practices/core/model_associations_spec.rb +10 -10
- data/spec/rails_best_practices/core/model_attributes_spec.rb +10 -10
- data/spec/rails_best_practices/core/modules_spec.rb +10 -10
- data/spec/rails_best_practices/core/routes_spec.rb +10 -10
- data/spec/rails_best_practices/core/runner_spec.rb +4 -4
- data/spec/rails_best_practices/core_ext/erubis_spec.rb +7 -7
- data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +7 -7
- data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
- data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
- data/spec/rails_best_practices/prepares/config_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +26 -26
- data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +6 -6
- data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +5 -5
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +108 -108
- data/spec/rails_best_practices/prepares/route_prepare_spec.rb +77 -77
- data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +10 -10
- data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +27 -27
- data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +11 -11
- data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +17 -17
- data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +10 -10
- data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +16 -16
- data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +13 -13
- data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +10 -10
- data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +11 -11
- data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +16 -16
- data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +33 -33
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +106 -106
- data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +29 -29
- data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +15 -15
- data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +15 -15
- data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +29 -29
- data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +28 -28
- data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +23 -23
- data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +6 -6
- data/spec/spec_helper.rb +1 -1
- metadata +7 -7
@@ -16,7 +16,7 @@ module RailsBestPractices
|
|
16
16
|
class AddModelVirtualAttributeReview < Review
|
17
17
|
interesting_nodes :def
|
18
18
|
interesting_files CONTROLLER_FILES
|
19
|
-
url
|
19
|
+
url 'https://rails-bestpractices.com/posts/2010/07/21/add-model-virtual-attribute/'
|
20
20
|
|
21
21
|
# check method define nodes to see if there are some attribute assignments that can use model virtual attribute instead in review process.
|
22
22
|
#
|
@@ -60,7 +60,7 @@ module RailsBestPractices
|
|
60
60
|
# and if the arguments of this attribute assignments has duplicated entries (different message and same arguments),
|
61
61
|
# then this node needs to add a virtual attribute.
|
62
62
|
def call_assignment(node)
|
63
|
-
if [
|
63
|
+
if ['save', 'save!'].include? node.message.to_s
|
64
64
|
receiver = node.receiver.to_s
|
65
65
|
add_error "add model virtual attribute (for #{receiver})" if params_dup?(assignments(receiver).collect {|h| h[:arguments]})
|
66
66
|
end
|
@@ -25,7 +25,7 @@ module RailsBestPractices
|
|
25
25
|
class AlwaysAddDbIndexReview < Review
|
26
26
|
interesting_nodes :command, :command_call
|
27
27
|
interesting_files SCHEMA_FILE
|
28
|
-
url
|
28
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/always-add-db-index/'
|
29
29
|
|
30
30
|
def initialize(options={})
|
31
31
|
super(options)
|
@@ -41,7 +41,7 @@ module RailsBestPractices
|
|
41
41
|
add_callback :start_command_call do |node|
|
42
42
|
if %w(integer string).include? node.message.to_s
|
43
43
|
remember_foreign_key_columns(node)
|
44
|
-
elsif
|
44
|
+
elsif 'index' == node.message.to_s
|
45
45
|
remember_index_columns_inside_table(node)
|
46
46
|
end
|
47
47
|
end
|
@@ -55,9 +55,9 @@ module RailsBestPractices
|
|
55
55
|
# then remember it with _id suffixed column as polymorphic foreign key.
|
56
56
|
add_callback :start_command do |node|
|
57
57
|
case node.message.to_s
|
58
|
-
when
|
58
|
+
when 'create_table'
|
59
59
|
remember_table_nodes(node)
|
60
|
-
when
|
60
|
+
when 'add_index'
|
61
61
|
remember_index_columns_outside_table(node)
|
62
62
|
end
|
63
63
|
end
|
@@ -134,7 +134,7 @@ module RailsBestPractices
|
|
134
134
|
|
135
135
|
if foreign_id_column
|
136
136
|
index_node = node.arguments.all.last.hash_value('index')
|
137
|
-
if index_node.present? and
|
137
|
+
if index_node.present? and 'false' != index_node.to_s
|
138
138
|
@index_columns[table_name] ||= []
|
139
139
|
@index_columns[table_name] << foreign_id_column
|
140
140
|
end
|
@@ -147,7 +147,7 @@ module RailsBestPractices
|
|
147
147
|
foreign_keys.delete_if do |key|
|
148
148
|
if key =~ /_id$/
|
149
149
|
class_name = Prepares.model_associations.get_association_class_name(table, key[0..-4])
|
150
|
-
class_name ? !@table_nodes[class_name.gsub(
|
150
|
+
class_name ? !@table_nodes[class_name.gsub('::', '').tableize] : !@table_nodes[key[0..-4].pluralize]
|
151
151
|
end
|
152
152
|
end
|
153
153
|
end
|
@@ -167,7 +167,7 @@ module RailsBestPractices
|
|
167
167
|
foreign_id_keys = foreign_keys.select { |key| key.size == 1 && key.first =~ /_id/ }
|
168
168
|
foreign_type_keys = foreign_keys.select { |key| key.size == 1 && key.first =~ /_type/ }
|
169
169
|
foreign_id_keys.each do |id_key|
|
170
|
-
if type_key = foreign_type_keys.detect { |type_key| type_key.first == id_key.first.sub(/_id/, '') +
|
170
|
+
if type_key = foreign_type_keys.detect { |type_key| type_key.first == id_key.first.sub(/_id/, '') + '_type' }
|
171
171
|
foreign_keys.delete(id_key)
|
172
172
|
foreign_keys.delete(type_key)
|
173
173
|
foreign_keys << id_key + type_key
|
@@ -15,7 +15,7 @@ module RailsBestPractices
|
|
15
15
|
include Classable
|
16
16
|
interesting_nodes :call, :command_call, :method_add_arg, :if, :ifop, :elsif, :unless, :if_mod, :unless_mod, :assign, :binary
|
17
17
|
interesting_files ALL_FILES
|
18
|
-
url
|
18
|
+
url 'https://rails-bestpractices.com/posts/2012/11/02/check-the-return-value-of-save-otherwise-use-save/'
|
19
19
|
|
20
20
|
add_callback :start_if, :start_ifop, :start_elsif, :start_unless, :start_if_mod, :start_unless_mod do |node|
|
21
21
|
@used_return_value_of = node.conditional_statement.all_conditions
|
@@ -12,12 +12,12 @@ module RailsBestPractices
|
|
12
12
|
class DefaultScopeIsEvilReview < Review
|
13
13
|
interesting_nodes :command
|
14
14
|
interesting_files MODEL_FILES
|
15
|
-
url
|
15
|
+
url 'https://rails-bestpractices.com/posts/2013/06/15/default_scope-is-evil/'
|
16
16
|
|
17
17
|
# check all command nodes' message
|
18
18
|
add_callback :start_command do |node|
|
19
|
-
if
|
20
|
-
add_error
|
19
|
+
if 'default_scope' == node.message.to_s
|
20
|
+
add_error 'default_scope is evil'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -15,12 +15,12 @@ module RailsBestPractices
|
|
15
15
|
class DryBundlerInCapistranoReview < Review
|
16
16
|
interesting_nodes :command
|
17
17
|
interesting_files DEPLOY_FILES
|
18
|
-
url
|
18
|
+
url 'https://rails-bestpractices.com/posts/2010/09/02/dry-bundler-in-capistrano/'
|
19
19
|
|
20
20
|
# check call node to see if it is with message "namespace" and argument "bundler".
|
21
21
|
add_callback :start_command do |node|
|
22
|
-
if
|
23
|
-
add_error
|
22
|
+
if 'namespace' == node.message.to_s && 'bundler' == node.arguments.all[0].to_s
|
23
|
+
add_error 'dry bundler in capistrano'
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -16,7 +16,7 @@ module RailsBestPractices
|
|
16
16
|
# check hash node to see if it is ruby 1.8 style.
|
17
17
|
add_callback :start_hash, :start_bare_assoc_hash do |node|
|
18
18
|
if !empty_hash?(node) && hash_is_18?(node) && valid_keys?(node)
|
19
|
-
add_error
|
19
|
+
add_error 'change Hash Syntax to 1.9'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -21,7 +21,7 @@ module RailsBestPractices
|
|
21
21
|
class IsolateSeedDataReview < Review
|
22
22
|
interesting_nodes :call, :assign
|
23
23
|
interesting_files MIGRATION_FILES
|
24
|
-
url
|
24
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/isolating-seed-data/'
|
25
25
|
|
26
26
|
def initialize(options={})
|
27
27
|
super(options)
|
@@ -45,10 +45,10 @@ module RailsBestPractices
|
|
45
45
|
# and the receiver of the call node is included in @new_variables,
|
46
46
|
# then you should isolate it to seed data.
|
47
47
|
add_callback :start_call do |node|
|
48
|
-
if [
|
49
|
-
add_error(
|
50
|
-
elsif [
|
51
|
-
add_error(
|
48
|
+
if ['create', 'create!'].include? node.message.to_s
|
49
|
+
add_error('isolate seed data')
|
50
|
+
elsif ['save', 'save!'].include? node.message.to_s
|
51
|
+
add_error('isolate seed data') if new_record?(node)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -59,7 +59,7 @@ module RailsBestPractices
|
|
59
59
|
# then remember the left value as new variable.
|
60
60
|
def remember_new_variable(node)
|
61
61
|
right_value = node.right_value
|
62
|
-
if :method_add_arg == right_value.sexp_type &&
|
62
|
+
if :method_add_arg == right_value.sexp_type && 'new' == right_value.message.to_s
|
63
63
|
@new_variables << node.left_value.to_s
|
64
64
|
end
|
65
65
|
end
|
@@ -17,7 +17,7 @@ module RailsBestPractices
|
|
17
17
|
class KeepFindersOnTheirOwnModelReview < Review
|
18
18
|
interesting_nodes :method_add_arg
|
19
19
|
interesting_files MODEL_FILES
|
20
|
-
url
|
20
|
+
url 'https://rails-bestpractices.com/posts/2010/07/23/keep-finders-on-their-own-model/'
|
21
21
|
|
22
22
|
FINDERS = %w(find all first last)
|
23
23
|
|
@@ -31,7 +31,7 @@ module RailsBestPractices
|
|
31
31
|
#
|
32
32
|
# then it should keep finders on its own model.
|
33
33
|
add_callback :start_method_add_arg do |node|
|
34
|
-
add_error
|
34
|
+
add_error 'keep finders on their own model' if other_finder?(node)
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
@@ -16,7 +16,7 @@ module RailsBestPractices
|
|
16
16
|
class LawOfDemeterReview < Review
|
17
17
|
interesting_nodes :call
|
18
18
|
interesting_files ALL_FILES
|
19
|
-
url
|
19
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/the-law-of-demeter/'
|
20
20
|
|
21
21
|
ASSOCIATION_METHODS = %w(belongs_to has_one)
|
22
22
|
|
@@ -28,7 +28,7 @@ module RailsBestPractices
|
|
28
28
|
# then it violates the law of demeter.
|
29
29
|
add_callback :start_call do |node|
|
30
30
|
if :call == node.receiver.sexp_type && need_delegate?(node)
|
31
|
-
add_error
|
31
|
+
add_error 'law of demeter'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -45,8 +45,8 @@ module RailsBestPractices
|
|
45
45
|
association_name = node.receiver.message.to_s
|
46
46
|
association = model_associations.get_association(class_name, association_name)
|
47
47
|
attribute_name = node.message.to_s
|
48
|
-
association && ASSOCIATION_METHODS.include?(association[
|
49
|
-
is_association_attribute?(association[
|
48
|
+
association && ASSOCIATION_METHODS.include?(association['meta']) &&
|
49
|
+
is_association_attribute?(association['class_name'], association_name, attribute_name)
|
50
50
|
end
|
51
51
|
|
52
52
|
def is_association_attribute?(association_class, association_name, attribute_name)
|
@@ -12,7 +12,7 @@ module RailsBestPractices
|
|
12
12
|
class MoveCodeIntoControllerReview < Review
|
13
13
|
interesting_nodes :method_add_arg, :assign
|
14
14
|
interesting_files VIEW_FILES
|
15
|
-
url
|
15
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/move-code-into-controller/'
|
16
16
|
|
17
17
|
FINDERS = %w(find all first last)
|
18
18
|
|
@@ -22,7 +22,7 @@ module RailsBestPractices
|
|
22
22
|
# and the message of the method_add_arg node is one of the find, all, first and last,
|
23
23
|
# then it is a finder and should be moved to controller.
|
24
24
|
add_callback :start_method_add_arg do |node|
|
25
|
-
add_error
|
25
|
+
add_error 'move code into controller' if finder?(node)
|
26
26
|
end
|
27
27
|
|
28
28
|
# check assign nodes.
|
@@ -31,7 +31,7 @@ module RailsBestPractices
|
|
31
31
|
# and the message of the right value node is one of the find, all, first and last,
|
32
32
|
# then it is a finder and should be moved to controller.
|
33
33
|
add_callback :start_assign do |node|
|
34
|
-
add_error
|
34
|
+
add_error 'move code into controller', node.file, node.right_value.line_number if finder?(node.right_value)
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
@@ -19,7 +19,7 @@ module RailsBestPractices
|
|
19
19
|
class MoveCodeIntoHelperReview < Review
|
20
20
|
interesting_nodes :method_add_arg
|
21
21
|
interesting_files VIEW_FILES
|
22
|
-
url
|
22
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/move-code-into-helper/'
|
23
23
|
|
24
24
|
def initialize(options = {})
|
25
25
|
super(options)
|
@@ -43,7 +43,7 @@ module RailsBestPractices
|
|
43
43
|
# and the size of array is greater than @array_count you defined,
|
44
44
|
# then it is complext.
|
45
45
|
def complex_select_options?(node)
|
46
|
-
|
46
|
+
'options_for_select' == node[1].message.to_s &&
|
47
47
|
:array == node.arguments.all.first.sexp_type &&
|
48
48
|
node.arguments.all.first.array_size > @array_count
|
49
49
|
end
|
@@ -13,7 +13,7 @@ module RailsBestPractices
|
|
13
13
|
class MoveCodeIntoModelReview < Review
|
14
14
|
interesting_nodes :if, :unless, :elsif, :ifop, :if_mod, :unless_mod
|
15
15
|
interesting_files VIEW_FILES
|
16
|
-
url
|
16
|
+
url 'https://rails-bestpractices.com/posts/2010/07/24/move-code-into-model/'
|
17
17
|
|
18
18
|
def initialize(options={})
|
19
19
|
super(options)
|
@@ -15,7 +15,7 @@ module RailsBestPractices
|
|
15
15
|
class MoveFinderToNamedScopeReview < Review
|
16
16
|
interesting_nodes :method_add_arg
|
17
17
|
interesting_files CONTROLLER_FILES
|
18
|
-
url
|
18
|
+
url 'https://rails-bestpractices.com/posts/2010/07/14/move-finder-to-named_scope/'
|
19
19
|
|
20
20
|
FINDERS = %w(find all first last)
|
21
21
|
|
@@ -23,7 +23,7 @@ module RailsBestPractices
|
|
23
23
|
# and it has a hash argument,
|
24
24
|
# then the call node is the finder that should be moved to model's named_scope.
|
25
25
|
add_callback :start_method_add_arg do |node|
|
26
|
-
add_error
|
26
|
+
add_error 'move finder to named_scope' if finder?(node)
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -15,7 +15,7 @@ module RailsBestPractices
|
|
15
15
|
class MoveModelLogicIntoModelReview < Review
|
16
16
|
interesting_nodes :def
|
17
17
|
interesting_files CONTROLLER_FILES
|
18
|
-
url
|
18
|
+
url 'https://rails-bestpractices.com/posts/2010/07/21/move-model-logic-into-the-model/'
|
19
19
|
|
20
20
|
def initialize(options = {})
|
21
21
|
super(options)
|
@@ -24,7 +24,7 @@ module RailsBestPractices
|
|
24
24
|
class NeedlessDeepNestingReview < Review
|
25
25
|
interesting_nodes :method_add_block
|
26
26
|
interesting_files ROUTE_FILES
|
27
|
-
url
|
27
|
+
url 'https://rails-bestpractices.com/posts/2010/07/22/needless-deep-nesting/'
|
28
28
|
|
29
29
|
def initialize(options = {})
|
30
30
|
super(options)
|
@@ -61,16 +61,16 @@ module RailsBestPractices
|
|
61
61
|
# if so, it is the needless deep nesting.
|
62
62
|
def recursively_check(node)
|
63
63
|
shallow = @shallow_nodes.include? node
|
64
|
-
if [:command_call, :command].include?(node[1].sexp_type) && [
|
64
|
+
if [:command_call, :command].include?(node[1].sexp_type) && ['resources', 'resource'].include?(node[1].message.to_s)
|
65
65
|
hash_node = node[1].arguments.grep_node(sexp_type: :bare_assoc_hash)
|
66
|
-
shallow = (hash_node &&
|
66
|
+
shallow = (hash_node && 'true' == hash_node.hash_value('shallow').to_s) unless shallow
|
67
67
|
@counter += 1
|
68
68
|
node.block_node.statements.each do |stmt_node|
|
69
69
|
@shallow_nodes << stmt_node if shallow
|
70
70
|
recursively_check(stmt_node)
|
71
71
|
end
|
72
72
|
@counter -= 1
|
73
|
-
elsif [:command_call, :command].include?(node.sexp_type) && [
|
73
|
+
elsif [:command_call, :command].include?(node.sexp_type) && ['resources', 'resource'].include?(node.message.to_s)
|
74
74
|
add_error "needless deep nesting (nested_count > #{@nested_count})", @file, node.line_number if @counter >= @nested_count && !@shallow_nodes.include?(node)
|
75
75
|
end
|
76
76
|
end
|
@@ -13,11 +13,11 @@ module RailsBestPractices
|
|
13
13
|
class NotRescueExceptionReview < Review
|
14
14
|
interesting_nodes :rescue
|
15
15
|
interesting_files ALL_FILES
|
16
|
-
url
|
16
|
+
url 'https://rails-bestpractices.com/posts/2012/11/01/don-t-rescue-exception-rescue-standarderror/'
|
17
17
|
|
18
18
|
# check rescue node to see if its type is Exception
|
19
19
|
add_callback :start_rescue do |rescue_node|
|
20
|
-
if rescue_node.exception_classes.any? { |rescue_class|
|
20
|
+
if rescue_node.exception_classes.any? { |rescue_class| 'Exception' == rescue_class.to_s }
|
21
21
|
add_error "Don't rescue Exception", rescue_node.file, rescue_node.exception_classes.first.line_number
|
22
22
|
end
|
23
23
|
end
|
@@ -19,13 +19,13 @@ module RailsBestPractices
|
|
19
19
|
class NotUseDefaultRouteReview < Review
|
20
20
|
interesting_nodes :command_call, :command
|
21
21
|
interesting_files ROUTE_FILES
|
22
|
-
url
|
22
|
+
url 'https://rails-bestpractices.com/posts/2010/07/22/not-use-default-route-if-you-use-restful-design/'
|
23
23
|
|
24
24
|
# check all command nodes
|
25
25
|
add_callback :start_command do |node|
|
26
|
-
if
|
27
|
-
|
28
|
-
add_error
|
26
|
+
if 'match' == node.message.to_s &&
|
27
|
+
':controller(/:action(/:id(.:format)))' == node.arguments.all.first.to_s
|
28
|
+
add_error 'not use default route'
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -12,12 +12,12 @@ module RailsBestPractices
|
|
12
12
|
class NotUseTimeAgoInWordsReview < Review
|
13
13
|
interesting_nodes :fcall
|
14
14
|
interesting_files VIEW_FILES, HELPER_FILES
|
15
|
-
url
|
15
|
+
url 'https://rails-bestpractices.com/posts/2012/02/10/not-use-time_ago_in_words/'
|
16
16
|
|
17
17
|
# check fcall node to see if its message is time_ago_in_words or distance_of_time_in_words_to_now
|
18
18
|
add_callback :start_fcall do |node|
|
19
|
-
if
|
20
|
-
add_error
|
19
|
+
if 'time_ago_in_words' == node.message.to_s || 'distance_of_time_in_words_to_now' == node.message.to_s
|
20
|
+
add_error 'not use time_ago_in_words'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -17,7 +17,7 @@ module RailsBestPractices
|
|
17
17
|
class OveruseRouteCustomizationsReview < Review
|
18
18
|
interesting_nodes :command_call, :method_add_block
|
19
19
|
interesting_files ROUTE_FILES
|
20
|
-
url
|
20
|
+
url 'https://rails-bestpractices.com/posts/2010/07/22/overuse-route-customizations/'
|
21
21
|
|
22
22
|
VERBS = %w(get post update delete)
|
23
23
|
|
@@ -46,7 +46,7 @@ module RailsBestPractices
|
|
46
46
|
# then calculate the count of call nodes, whose message is get, post, update or delete,
|
47
47
|
# it is just the count of member and collection custom routes.
|
48
48
|
def member_and_collection_count_for_rails3(node)
|
49
|
-
|
49
|
+
'resources' == node[1].message.to_s ? node.grep_nodes_count(sexp_type: :command, message: VERBS) : 0
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -13,7 +13,7 @@ module RailsBestPractices
|
|
13
13
|
class ProtectMassAssignmentReview < Review
|
14
14
|
interesting_files MODEL_FILES
|
15
15
|
interesting_nodes :class, :command, :var_ref, :vcall, :fcall
|
16
|
-
url
|
16
|
+
url 'https://rails-bestpractices.com/posts/2012/03/06/protect-mass-assignment/'
|
17
17
|
|
18
18
|
# we treat it as mass assignment by default.
|
19
19
|
add_callback :start_class do |node|
|
@@ -28,7 +28,7 @@ module RailsBestPractices
|
|
28
28
|
add_callback :end_class do |node|
|
29
29
|
check_active_record(node)
|
30
30
|
|
31
|
-
add_error
|
31
|
+
add_error 'protect mass assignment' if @mass_assignement
|
32
32
|
end
|
33
33
|
|
34
34
|
# check if it is attr_accessible or attr_protected command,
|
@@ -54,19 +54,19 @@ module RailsBestPractices
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def check_activerecord_version
|
57
|
-
if Prepares.gems.gem_version(
|
57
|
+
if Prepares.gems.gem_version('activerecord').to_i > 3
|
58
58
|
@mass_assignement = false
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
def check_whitelist_attributes_config
|
63
|
-
if
|
63
|
+
if 'true' == Prepares.configs['config.active_record.whitelist_attributes']
|
64
64
|
@whitelist_attributes = true
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
def check_include_forbidden_attributes_protection_config
|
69
|
-
if
|
69
|
+
if 'true' == Prepares.configs['railsbp.include_forbidden_attributes_protection']
|
70
70
|
@mass_assignement = false
|
71
71
|
end
|
72
72
|
end
|
@@ -78,25 +78,25 @@ module RailsBestPractices
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def check_strong_parameters(command_node)
|
81
|
-
if
|
81
|
+
if 'include' == command_node.message.to_s && 'ActiveModel::ForbiddenAttributesProtection' == command_node.arguments.all.first.to_s
|
82
82
|
@mass_assignement = false
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
def check_devise(command_node)
|
87
|
-
if
|
87
|
+
if 'devise' == command_node.message.to_s
|
88
88
|
@mass_assignement = false
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
def check_authlogic(node)
|
93
|
-
if [node.to_s, node.message.to_s].include?
|
93
|
+
if [node.to_s, node.message.to_s].include? 'acts_as_authentic'
|
94
94
|
@mass_assignement = false
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
98
|
def check_active_record(const_path_ref_node)
|
99
|
-
if
|
99
|
+
if 'ActiveRecord::Base' != const_path_ref_node.base_class.to_s
|
100
100
|
@mass_assignement = false
|
101
101
|
end
|
102
102
|
end
|