rails_best_practices 1.16.0 → 1.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -4
- data/CHANGELOG.md +6 -0
- data/lib/rails_best_practices/analyzer.rb +0 -1
- data/lib/rails_best_practices/core/check.rb +2 -1
- data/lib/rails_best_practices/core/checks_loader.rb +1 -0
- data/lib/rails_best_practices/core/klasses.rb +6 -11
- data/lib/rails_best_practices/core/methods.rb +1 -0
- data/lib/rails_best_practices/core/runner.rb +1 -0
- data/lib/rails_best_practices/prepares/model_prepare.rb +1 -0
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +1 -0
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +14 -3
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +1 -0
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +1 -0
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +1 -0
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +1 -0
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +1 -0
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +1 -0
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +1 -0
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +1 -0
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +1 -0
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +4 -3
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +1 -0
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +1 -0
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +1 -0
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +1 -0
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +1 -0
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +1 -0
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +1 -0
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +3 -2
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +1 -0
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +1 -0
- data/lib/rails_best_practices/reviews/use_observer_review.rb +1 -0
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +1 -0
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +3 -2
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +1 -0
- data/lib/rails_best_practices/version.rb +1 -1
- data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +27 -0
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +5 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0b67ef3e8abe665b14bf2dd398755f5b1d84e05
|
4
|
+
data.tar.gz: 4ea8cfbcb9a26b10b070e86b2deac14e2f9ea751
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c032c3904c6f27437c7b8be4a728c74ab543d6f14d1c2d620d8dac8dda029de46aa15f52c31b86d07e45dee2544f7165d991c7dc652731c7227e76970574eefe
|
7
|
+
data.tar.gz: dada2172b41c479b90ec443f8a99a9a04bf68833ceea23b5f39ba5e9c572b8686797079c1c15eead93c2a7ea066fe40970f4257342055215574b804e6049e0a9
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -130,7 +130,8 @@ module RailsBestPractices
|
|
130
130
|
|
131
131
|
# remember the class name
|
132
132
|
add_callback :start_class do |node|
|
133
|
-
|
133
|
+
base_class_name = node.base_class.is_a?(CodeAnalyzer::Nil) ? nil : node.base_class.to_s
|
134
|
+
@klass = Core::Klass.new(node.class_name.to_s, base_class_name, classable_modules)
|
134
135
|
klasses << @klass
|
135
136
|
end
|
136
137
|
|
@@ -14,19 +14,14 @@ module RailsBestPractices
|
|
14
14
|
|
15
15
|
# Class info includes class name, extend class name and module names.
|
16
16
|
class Klass
|
17
|
+
attr_reader :extend_class_name, :class_name
|
18
|
+
|
17
19
|
def initialize(class_name, extend_class_name, modules)
|
18
|
-
@class_name = class_name
|
19
|
-
@extend_class_name = extend_class_name
|
20
20
|
@modules = modules.dup
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def extend_class_name
|
28
|
-
if @extend_class_name.present?
|
29
|
-
@modules.map { |modu| "#{modu}::" }.join("") + @extend_class_name
|
21
|
+
base = @modules.map { |modu| "#{modu}::" }.join("")
|
22
|
+
@class_name = base + class_name
|
23
|
+
if extend_class_name
|
24
|
+
@extend_class_name = base + extend_class_name
|
30
25
|
end
|
31
26
|
end
|
32
27
|
|
@@ -10,8 +10,9 @@ module RailsBestPractices
|
|
10
10
|
# Review process:
|
11
11
|
# only check the command and command_calls nodes and at the end of review process,
|
12
12
|
# if the receiver of command node is "create_table", then remember the table names
|
13
|
-
# if the receiver of command_call node is "integer" and suffix with
|
14
|
-
# if the
|
13
|
+
# if the receiver of command_call node is "integer" or "string" and suffix with _id, then remember it as foreign key
|
14
|
+
# if the receiver of command_call node is "string", the name of it is _type suffixed and there is an integer or string column _id suffixed, then remember it as polymorphic foreign key
|
15
|
+
# if the receiver of command_call node is remembered as foreign key and it have argument non-false "index", then remember the index columns
|
15
16
|
# if the receiver of command node is "add_index", then remember the index columns
|
16
17
|
# after all of these, at the end of review process
|
17
18
|
#
|
@@ -81,6 +82,7 @@ module RailsBestPractices
|
|
81
82
|
end
|
82
83
|
|
83
84
|
private
|
85
|
+
|
84
86
|
# remember the node as index columns, when used outside a table
|
85
87
|
# block, i.e.
|
86
88
|
# add_index :table_name, :column_name
|
@@ -109,7 +111,6 @@ module RailsBestPractices
|
|
109
111
|
@table_nodes[@table_name] = node
|
110
112
|
end
|
111
113
|
|
112
|
-
|
113
114
|
# remember foreign key columns
|
114
115
|
def remember_foreign_key_columns(node)
|
115
116
|
table_name = @table_name
|
@@ -121,12 +122,22 @@ module RailsBestPractices
|
|
121
122
|
else
|
122
123
|
@foreign_keys[table_name] << foreign_key_column
|
123
124
|
end
|
125
|
+
foreign_id_column = foreign_key_column
|
124
126
|
elsif foreign_key_column =~ /(.*?)_type$/
|
125
127
|
if @foreign_keys[table_name].delete("#{$1}_id")
|
126
128
|
@foreign_keys[table_name] << ["#{$1}_id", "#{$1}_type"]
|
127
129
|
else
|
128
130
|
@foreign_keys[table_name] << foreign_key_column
|
129
131
|
end
|
132
|
+
foreign_id_column = "#{$1}_id"
|
133
|
+
end
|
134
|
+
|
135
|
+
if foreign_id_column
|
136
|
+
index_node = node.arguments.all.last.hash_value('index')
|
137
|
+
if index_node.present? and "false" != index_node.to_s
|
138
|
+
@index_columns[table_name] ||= []
|
139
|
+
@index_columns[table_name] << foreign_id_column
|
140
|
+
end
|
130
141
|
end
|
131
142
|
end
|
132
143
|
|
@@ -18,7 +18,7 @@ module RailsBestPractices
|
|
18
18
|
# we treat it as mass assignment by default.
|
19
19
|
add_callback :start_class do |node|
|
20
20
|
@mass_assignement = true
|
21
|
-
|
21
|
+
check_activerecord_version
|
22
22
|
check_whitelist_attributes_config
|
23
23
|
check_include_forbidden_attributes_protection_config
|
24
24
|
end
|
@@ -52,8 +52,9 @@ module RailsBestPractices
|
|
52
52
|
end
|
53
53
|
|
54
54
|
private
|
55
|
-
|
56
|
-
|
55
|
+
|
56
|
+
def check_activerecord_version
|
57
|
+
if Prepares.gems.gem_version("activerecord").to_i > 3
|
57
58
|
@mass_assignement = false
|
58
59
|
end
|
59
60
|
end
|
data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb
CHANGED
@@ -48,6 +48,7 @@ module RailsBestPractices
|
|
48
48
|
end
|
49
49
|
|
50
50
|
private
|
51
|
+
|
51
52
|
# check the call node to see if it is with message "save" or "save!",
|
52
53
|
# and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
|
53
54
|
# then it is a complex creation, should be replaced with factory method.
|
@@ -38,13 +38,14 @@ module RailsBestPractices
|
|
38
38
|
@first_sentences.each do |first_sentence, def_nodes|
|
39
39
|
if def_nodes.size > @customize_count
|
40
40
|
add_error "use before_filter for #{def_nodes.map { |node| node.method_name.to_s }.join(',')}",
|
41
|
-
|
42
|
-
|
41
|
+
node.file,
|
42
|
+
def_nodes.map(&:line_number).join(',')
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
|
+
|
48
49
|
# check method define node, and remember the first sentence.
|
49
50
|
def remember_first_sentence(node)
|
50
51
|
first_sentence = node.body.statements.first
|
@@ -42,13 +42,14 @@ module RailsBestPractices
|
|
42
42
|
if query_attribute_node = query_attribute_node(condition_node)
|
43
43
|
receiver_node = query_attribute_node.receiver
|
44
44
|
add_error "use query attribute (#{receiver_node.receiver}.#{receiver_node.message}?)",
|
45
|
-
|
46
|
-
|
45
|
+
node.file,
|
46
|
+
query_attribute_node.line_number
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
private
|
52
|
+
|
52
53
|
# recursively check conditional statement nodes to see if there is a call node that may be
|
53
54
|
# possible query attribute.
|
54
55
|
def query_attribute_node(conditional_statement_node)
|
@@ -295,6 +295,33 @@ module RailsBestPractices
|
|
295
295
|
runner.after_review
|
296
296
|
expect(runner.errors.size).to eq(0)
|
297
297
|
end
|
298
|
+
|
299
|
+
it "should detect index option in column creation" do
|
300
|
+
content = <<-EOF
|
301
|
+
ActiveRecord::Schema.define(version: 20100603080629) do
|
302
|
+
create_table "comments", force: true do |t|
|
303
|
+
t.string "content"
|
304
|
+
t.integer "post_id", index: true
|
305
|
+
t.string "user_id", index: { unique: true }
|
306
|
+
t.integer "image_id", index: false
|
307
|
+
t.integer "link_id"
|
308
|
+
end
|
309
|
+
create_table "posts", force: true do |t|
|
310
|
+
end
|
311
|
+
create_table "users", id: :string, force: true do |t|
|
312
|
+
end
|
313
|
+
create_table "images", force: true do |t|
|
314
|
+
end
|
315
|
+
create_table "links", force: true do |t|
|
316
|
+
end
|
317
|
+
end
|
318
|
+
EOF
|
319
|
+
runner.review('db/schema.rb', content)
|
320
|
+
runner.after_review
|
321
|
+
expect(runner.errors.size).to eq(2)
|
322
|
+
expect(runner.errors[0].to_s).to eq("db/schema.rb:2 - always add db index (comments => [image_id])")
|
323
|
+
expect(runner.errors[1].to_s).to eq("db/schema.rb:2 - always add db index (comments => [link_id])")
|
324
|
+
end
|
298
325
|
end
|
299
326
|
end
|
300
327
|
end
|
@@ -138,13 +138,13 @@ module RailsBestPractices
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
context "
|
142
|
-
it "should not protect mass assignment for
|
141
|
+
context "activerecord 4" do
|
142
|
+
it "should not protect mass assignment for activerecord 4" do
|
143
143
|
content =<<-EOF
|
144
144
|
GEM
|
145
145
|
remote: http://rubygems.org
|
146
146
|
specs:
|
147
|
-
|
147
|
+
activerecord (4.0.0)
|
148
148
|
EOF
|
149
149
|
runner.prepare('Gemfile.lock', content)
|
150
150
|
content =<<-EOF
|
@@ -155,12 +155,12 @@ module RailsBestPractices
|
|
155
155
|
expect(runner.errors.size).to eq(0)
|
156
156
|
end
|
157
157
|
|
158
|
-
it "should protect mass assignment for
|
158
|
+
it "should protect mass assignment for activerecord 3" do
|
159
159
|
content =<<-EOF
|
160
160
|
GEM
|
161
161
|
remote: http://rubygems.org
|
162
162
|
specs:
|
163
|
-
|
163
|
+
activerecord (3.2.13)
|
164
164
|
EOF
|
165
165
|
runner.prepare('Gemfile.lock', content)
|
166
166
|
content =<<-EOF
|
@@ -172,7 +172,6 @@ module RailsBestPractices
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
-
|
176
175
|
it "should not check ignored files" do
|
177
176
|
runner = Core::Runner.new(prepares: [Prepares::GemfilePrepare.new, Prepares::ConfigPrepare.new, Prepares::InitializerPrepare.new],
|
178
177
|
reviews: ProtectMassAssignmentReview.new(ignored_files: /app\/models\/user\.rb/))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_best_practices
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|