rails_best_practices 1.16.0 → 1.17.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.
- 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
|