rails_best_practices 0.4.6 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +2 -0
- data/lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb +1 -1
- data/lib/rails_best_practices/checks/always_add_db_index_check.rb +4 -4
- data/lib/rails_best_practices/checks/check.rb +5 -1
- data/lib/rails_best_practices/checks/dry_bundler_in_capistrano_check.rb +1 -1
- data/lib/rails_best_practices/checks/isolate_seed_data_check.rb +4 -4
- data/lib/rails_best_practices/checks/law_of_demeter_check.rb +3 -3
- data/lib/rails_best_practices/checks/move_code_into_model_check.rb +1 -1
- data/lib/rails_best_practices/checks/move_model_logic_into_model_check.rb +1 -1
- data/lib/rails_best_practices/checks/overuse_route_customizations_check.rb +1 -1
- data/lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb +1 -1
- data/lib/rails_best_practices/checks/use_model_association_check.rb +1 -1
- data/lib/rails_best_practices/checks/use_observer_check.rb +2 -2
- data/lib/rails_best_practices/checks/use_query_attribute_check.rb +83 -0
- data/lib/rails_best_practices/checks.rb +1 -0
- data/lib/rails_best_practices/core/core_ext.rb +0 -11
- data/lib/rails_best_practices/core/runner.rb +8 -4
- data/lib/rails_best_practices/core/visitable_sexp.rb +35 -9
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.yml +1 -0
- metadata +28 -31
data/README.textile
CHANGED
@@ -89,6 +89,7 @@ MoveCodeIntoHelperCheck: { array_count: 3 }
|
|
89
89
|
ReplaceInstanceVariableWithLocalVariableCheck: { }
|
90
90
|
DryBundlerInCapistranoCheck: { }
|
91
91
|
UseSayWithTimeInMigrationsCheck: { }
|
92
|
+
UseQueryAttributeCheck: { }
|
92
93
|
</code></pre>
|
93
94
|
|
94
95
|
*************************************************
|
@@ -112,6 +113,7 @@ h2. Implementation
|
|
112
113
|
## Keep Finders on Their Own Model (rails2 only)
|
113
114
|
## the Law of Demeter
|
114
115
|
## Use Observer
|
116
|
+
## Use Query Attribute
|
115
117
|
|
116
118
|
* Migration
|
117
119
|
## Isolating Seed Data
|
@@ -50,7 +50,7 @@ module RailsBestPractices
|
|
50
50
|
def call_assignment(node)
|
51
51
|
if node.message == :save
|
52
52
|
variable = node.subject
|
53
|
-
add_error "add model virtual attribute (for #{
|
53
|
+
add_error "add model virtual attribute (for #{variable})" if params_dup?(@variables[variable].collect {|h| h[:arguments]})
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -27,9 +27,9 @@ module RailsBestPractices
|
|
27
27
|
elsif :call == node.node_type
|
28
28
|
case node.message
|
29
29
|
when :create_table
|
30
|
-
@table_name = node.arguments[1].
|
30
|
+
@table_name = node.arguments[1].to_s
|
31
31
|
when :integer
|
32
|
-
column_name = node.arguments[1].
|
32
|
+
column_name = node.arguments[1].to_s
|
33
33
|
if column_name =~ /_id$/ and !indexed?(@table_name, column_name)
|
34
34
|
add_error "always add db index (#@table_name => #{column_name})", node.file, node.line
|
35
35
|
end
|
@@ -40,8 +40,8 @@ module RailsBestPractices
|
|
40
40
|
private
|
41
41
|
def find_index_columns(node)
|
42
42
|
node.grep_nodes({:node_type => :call, :message => :add_index}).each do |index_node|
|
43
|
-
table_name = index_node.arguments[1].
|
44
|
-
reference_column = eval(index_node.arguments[2].
|
43
|
+
table_name = index_node.arguments[1].to_s
|
44
|
+
reference_column = eval(index_node.arguments[2].to_s)
|
45
45
|
@index_columns << [table_name, reference_column]
|
46
46
|
end
|
47
47
|
end
|
@@ -4,7 +4,7 @@ require 'rails_best_practices/core/error'
|
|
4
4
|
module RailsBestPractices
|
5
5
|
module Checks
|
6
6
|
class Check
|
7
|
-
NODE_TYPES = [:call, :defn, :defs, :if, :unless, :class, :lasgn, :ivar, :block, :iter]
|
7
|
+
NODE_TYPES = [:call, :defn, :defs, :if, :unless, :class, :lasgn, :iasgn, :ivar, :lvar, :block, :iter]
|
8
8
|
|
9
9
|
CONTROLLER_FILES = /_controller\.rb$/
|
10
10
|
MIGRATION_FILES = /db\/migrate\/.*\.rb$/
|
@@ -60,6 +60,10 @@ module RailsBestPractices
|
|
60
60
|
line ||= @node.line
|
61
61
|
@errors << RailsBestPractices::Core::Error.new("#{file}", "#{line}", error)
|
62
62
|
end
|
63
|
+
|
64
|
+
def equal?(node, expected)
|
65
|
+
node.to_s == expected or node.to_s == ':' + expected.to_s
|
66
|
+
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -18,7 +18,7 @@ module RailsBestPractices
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def evaluate_start(node)
|
21
|
-
if :namespace == node.message and "bundler"
|
21
|
+
if :namespace == node.message and equal?(node.arguments[1], "bundler")
|
22
22
|
add_error "dry bundler in capistrano"
|
23
23
|
end
|
24
24
|
end
|
@@ -9,7 +9,7 @@ module RailsBestPractices
|
|
9
9
|
class IsolateSeedDataCheck < Check
|
10
10
|
|
11
11
|
def interesting_nodes
|
12
|
-
[:call, :lasgn]
|
12
|
+
[:call, :lasgn, :iasgn]
|
13
13
|
end
|
14
14
|
|
15
15
|
def interesting_files
|
@@ -24,7 +24,7 @@ module RailsBestPractices
|
|
24
24
|
def evaluate_start(node)
|
25
25
|
if [:create, :create!].include? node.message
|
26
26
|
add_error("isolate seed data")
|
27
|
-
elsif :lasgn
|
27
|
+
elsif [:lasgn, :iasgn].include? node.node_type
|
28
28
|
remember_new_variable(node)
|
29
29
|
elsif [:save, :save!].include? node.message
|
30
30
|
add_error("isolate seed data") if new_record?(node)
|
@@ -35,12 +35,12 @@ module RailsBestPractices
|
|
35
35
|
|
36
36
|
def remember_new_variable(node)
|
37
37
|
unless node.grep_nodes({:node_type => :call, :message => :new}).empty?
|
38
|
-
@new_variables << node.
|
38
|
+
@new_variables << node.left_value.to_s
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def new_record?(node)
|
43
|
-
@new_variables.include? node.subject.
|
43
|
+
@new_variables.include? node.subject.to_s
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -22,7 +22,7 @@ module RailsBestPractices
|
|
22
22
|
def evaluate_start(node)
|
23
23
|
if node.node_type == :class
|
24
24
|
remember_association(node)
|
25
|
-
elsif [:lvar, :ivar].include?(node.subject.node_type) and node.subject != s(:lvar, :_erbout)
|
25
|
+
elsif [:lvar, :ivar].include?(node.subject.subject.node_type) and node.subject != s(:lvar, :_erbout)
|
26
26
|
add_error "law of demeter" if need_delegate?(node)
|
27
27
|
end
|
28
28
|
end
|
@@ -34,13 +34,13 @@ module RailsBestPractices
|
|
34
34
|
(node.body.grep_nodes(:message => :belongs_to) + node.body.grep_nodes(:message => :has_one)).collect do |body_node|
|
35
35
|
class_name = node.subject.to_s.underscore
|
36
36
|
@associations[class_name] ||= []
|
37
|
-
@associations[class_name] << body_node.arguments[1].
|
37
|
+
@associations[class_name] << body_node.arguments[1].to_s
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def need_delegate?(node)
|
42
42
|
@associations.each do |class_name, associations|
|
43
|
-
return true if node.subject.
|
43
|
+
return true if node.subject.subject.to_s =~ /#{class_name}$/ and associations.find { |association| equal?(association, node.subject.message) }
|
44
44
|
end
|
45
45
|
false
|
46
46
|
end
|
@@ -32,7 +32,7 @@ module RailsBestPractices
|
|
32
32
|
end
|
33
33
|
|
34
34
|
@variables.each do |variable, count|
|
35
|
-
add_error "move model logic into model (#{variable
|
35
|
+
add_error "move model logic into model (#{variable} called_count > #{@called_count})" if count > @called_count
|
36
36
|
end
|
37
37
|
@variables = nil
|
38
38
|
end
|
@@ -47,7 +47,7 @@ module RailsBestPractices
|
|
47
47
|
return 0 if hash_nodes.empty?
|
48
48
|
hash_key_node = hash_nodes.first[1]
|
49
49
|
if :lit == hash_key_node.node_type and [:member, :collection].include? hash_key_node[1]
|
50
|
-
customize_hash = eval(hash_nodes.first.
|
50
|
+
customize_hash = eval(hash_nodes.first.to_s)
|
51
51
|
(customize_hash[:member].size || 0) + (customize_hash[:collection].size || 0)
|
52
52
|
end
|
53
53
|
end
|
@@ -48,7 +48,7 @@ module RailsBestPractices
|
|
48
48
|
def call_assignment(node)
|
49
49
|
if node.message == :save
|
50
50
|
variable = node.subject
|
51
|
-
add_error "replace complex creation with factory method (#{variable
|
51
|
+
add_error "replace complex creation with factory method (#{variable} attribute_assignment_count > #{@attrasgn_count})" if @variables[variable] > @attrasgn_count
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -40,7 +40,7 @@ module RailsBestPractices
|
|
40
40
|
def call_assignment(node)
|
41
41
|
if node.message == :save
|
42
42
|
variable = node.subject[1]
|
43
|
-
add_error "use model association (for #{node.subject
|
43
|
+
add_error "use model association (for #{node.subject})" if @variables[variable]
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -26,7 +26,7 @@ module RailsBestPractices
|
|
26
26
|
def evaluate_start(node)
|
27
27
|
if :after_create == node.message
|
28
28
|
remember_callbacks(node)
|
29
|
-
elsif :defn == node.node_type and @callbacks.
|
29
|
+
elsif :defn == node.node_type and @callbacks.find { |callback| equal?(callback, node.message_name) }
|
30
30
|
add_error "use observer" if use_observer?(node)
|
31
31
|
end
|
32
32
|
end
|
@@ -37,7 +37,7 @@ module RailsBestPractices
|
|
37
37
|
node.arguments[1..-1].each do |argument|
|
38
38
|
# ignore callback like after_create Comment.new
|
39
39
|
if :lit == argument.node_type
|
40
|
-
@callbacks << argument.
|
40
|
+
@callbacks << argument.to_s
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rails_best_practices/checks/check'
|
3
|
+
|
4
|
+
module RailsBestPractices
|
5
|
+
module Checks
|
6
|
+
# Check to make sure use query attribute instead of nil?, blank? and present?.
|
7
|
+
#
|
8
|
+
# Implementation:
|
9
|
+
# 1. check all models to save model names and association names.
|
10
|
+
# model names are used for detecting
|
11
|
+
# association name should not be detected as query attribute
|
12
|
+
# 2. check all method calls, if their subjects are model names and their messages are one of nil?,
|
13
|
+
# blank?, present? or == "", not pluralize and not in the association names,
|
14
|
+
# then they need to use query attribute.
|
15
|
+
class UseQueryAttributeCheck < Check
|
16
|
+
|
17
|
+
QUERY_METHODS = [:nil?, :blank?, :present?]
|
18
|
+
ASSOCIATION_METHODS = [:belongs_to, :has_one, :has_many, :has_and_belongs_to_many]
|
19
|
+
|
20
|
+
def interesting_nodes
|
21
|
+
[:if, :class, :call]
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
super
|
26
|
+
@klazzes = []
|
27
|
+
@associations = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate_start(node)
|
31
|
+
case node.node_type
|
32
|
+
when :class
|
33
|
+
remember_klazz(node)
|
34
|
+
when :call
|
35
|
+
remember_association(node) if ASSOCIATION_METHODS.include? node.message
|
36
|
+
when :if
|
37
|
+
add_error "use query attribute", node.file, node.line if need_query_attribute?(node.conditional_statement)
|
38
|
+
else
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def remember_klazz(class_node)
|
45
|
+
if class_node.file =~ MODLE_FILES
|
46
|
+
@klazzes << class_node.subject
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def remember_association(association_node)
|
51
|
+
@associations[@klazzes.last] ||= []
|
52
|
+
@associations[@klazzes.last] << association_node.arguments[1].to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def need_query_attribute?(conditional_statement_node)
|
56
|
+
case conditional_statement_node.node_type
|
57
|
+
when :and, :or
|
58
|
+
return need_query_attribute?(conditional_statement_node[1]) || need_query_attribute?(conditional_statement_node[2])
|
59
|
+
when :not
|
60
|
+
return need_query_attribute?(conditional_statement_node[1])
|
61
|
+
when :call
|
62
|
+
return true if query_method?(conditional_statement_node) or compare_with_empty_string?(conditional_statement_node)
|
63
|
+
end
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
def query_method?(node)
|
68
|
+
return false unless :call == node.subject.node_type
|
69
|
+
subject = node.subject.subject
|
70
|
+
message = node.subject.message
|
71
|
+
subject_ruby = subject.to_s
|
72
|
+
|
73
|
+
subject_ruby && @klazzes.find { |klazz| subject_ruby =~ %r|#{klazz.to_s.underscore}| and !@associations[klazz].find { |association| equal?(association, message) } } &&
|
74
|
+
message && message.to_s.pluralize != message.to_s &&
|
75
|
+
QUERY_METHODS.include?(node.message)
|
76
|
+
end
|
77
|
+
|
78
|
+
def compare_with_empty_string?(node)
|
79
|
+
:== == node.message and [:arglist, [:str, ""]] == node.arguments
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -20,3 +20,4 @@ require 'rails_best_practices/checks/move_code_into_helper_check'
|
|
20
20
|
require 'rails_best_practices/checks/replace_instance_variable_with_local_variable_check'
|
21
21
|
require 'rails_best_practices/checks/dry_bundler_in_capistrano_check'
|
22
22
|
require 'rails_best_practices/checks/use_say_with_time_in_migrations_check'
|
23
|
+
require 'rails_best_practices/checks/use_query_attribute_check'
|
@@ -5,17 +5,6 @@ module Enumerable
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
class String
|
9
|
-
# copy from rails
|
10
|
-
def underscore
|
11
|
-
self.gsub(/::/, '/').
|
12
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
13
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
14
|
-
tr("-", "_").
|
15
|
-
downcase
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
8
|
class NilClass
|
20
9
|
def method_missing(method_sym, *arguments, &block)
|
21
10
|
return nil
|
@@ -3,6 +3,7 @@ require 'rubygems'
|
|
3
3
|
require 'ruby_parser'
|
4
4
|
require 'erb'
|
5
5
|
require 'yaml'
|
6
|
+
require 'active_support/inflector'
|
6
7
|
|
7
8
|
module RailsBestPractices
|
8
9
|
module Core
|
@@ -30,10 +31,13 @@ module RailsBestPractices
|
|
30
31
|
content.gsub!(/#coding:US-ASCII\n/, '')
|
31
32
|
end
|
32
33
|
if filename =~ /.*\.haml$/
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
begin
|
35
|
+
require 'haml'
|
36
|
+
content = Haml::Engine.new(content).precompiled
|
37
|
+
# remove \xxx characters
|
38
|
+
content.gsub!(/\\\d{3}/, '')
|
39
|
+
rescue Haml::SyntaxError
|
40
|
+
end
|
37
41
|
end
|
38
42
|
node = parse(filename, content)
|
39
43
|
node.accept(@checker) if node
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'rubygems'
|
3
3
|
require 'sexp'
|
4
|
-
require 'ruby2ruby'
|
5
4
|
|
6
5
|
class Sexp
|
7
6
|
def accept(visitor)
|
@@ -48,7 +47,13 @@ class Sexp
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def subject
|
51
|
-
if [:attrasgn, :call, :
|
50
|
+
if [:attrasgn, :call, :class, :iter].include? node_type
|
51
|
+
self[1]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def left_value
|
56
|
+
if [:lasgn, :iasgn].include? node_type
|
52
57
|
self[1]
|
53
58
|
end
|
54
59
|
end
|
@@ -106,13 +111,34 @@ class Sexp
|
|
106
111
|
self[4][1]
|
107
112
|
end
|
108
113
|
end
|
109
|
-
|
110
|
-
def to_ruby
|
111
|
-
Ruby2Ruby.new.process(self) unless self.empty?
|
112
|
-
end
|
113
114
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
115
|
+
def to_s
|
116
|
+
if [:lvar, :ivar].include? node_type
|
117
|
+
self[1].to_s
|
118
|
+
elsif :str == node_type
|
119
|
+
self[1]
|
120
|
+
elsif :lit == node_type
|
121
|
+
":#{self[1]}"
|
122
|
+
elsif :array == node_type
|
123
|
+
"[\"#{self.children.collect(&:to_s).join('", "')}\"]"
|
124
|
+
elsif :hash == node_type
|
125
|
+
key_value = false # false is key, true is value
|
126
|
+
result = "{"
|
127
|
+
children.each do |child|
|
128
|
+
result += "#{child.to_s}#{key_value ? ', ' : ' => '}"
|
129
|
+
key_value = !key_value
|
130
|
+
end
|
131
|
+
result.sub!(/, $/, '')
|
132
|
+
result += "}"
|
133
|
+
end
|
117
134
|
end
|
135
|
+
|
136
|
+
#def to_ruby
|
137
|
+
#Ruby2Ruby.new.process(self) unless self.empty?
|
138
|
+
#end
|
139
|
+
|
140
|
+
#def to_ruby_string
|
141
|
+
#return nil if self.empty?
|
142
|
+
#eval(Ruby2Ruby.new.process(self)).to_s
|
143
|
+
#end
|
118
144
|
end
|
data/rails_best_practices.yml
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_best_practices
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Richard Huang
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-06 00:00:00 +08:00
|
19
19
|
default_executable: rails_best_practices
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -36,22 +36,6 @@ dependencies:
|
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
|
-
requirements:
|
41
|
-
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
hash: 23
|
44
|
-
segments:
|
45
|
-
- 1
|
46
|
-
- 2
|
47
|
-
- 4
|
48
|
-
version: 1.2.4
|
49
|
-
name: ruby2ruby
|
50
|
-
prerelease: false
|
51
|
-
type: :runtime
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
55
39
|
none: false
|
56
40
|
requirements:
|
57
41
|
- - ~>
|
@@ -65,9 +49,9 @@ dependencies:
|
|
65
49
|
name: progressbar
|
66
50
|
prerelease: false
|
67
51
|
type: :runtime
|
68
|
-
version_requirements: *
|
52
|
+
version_requirements: *id002
|
69
53
|
- !ruby/object:Gem::Dependency
|
70
|
-
requirement: &
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
71
55
|
none: false
|
72
56
|
requirements:
|
73
57
|
- - ~>
|
@@ -80,21 +64,33 @@ dependencies:
|
|
80
64
|
name: colored
|
81
65
|
prerelease: false
|
82
66
|
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
name: activesupport
|
79
|
+
prerelease: false
|
80
|
+
type: :runtime
|
83
81
|
version_requirements: *id004
|
84
82
|
- !ruby/object:Gem::Dependency
|
85
83
|
requirement: &id005 !ruby/object:Gem::Requirement
|
86
84
|
none: false
|
87
85
|
requirements:
|
88
|
-
- -
|
86
|
+
- - ~>
|
89
87
|
- !ruby/object:Gem::Version
|
90
|
-
hash:
|
88
|
+
hash: 13
|
91
89
|
segments:
|
92
90
|
- 2
|
93
91
|
- 0
|
94
|
-
-
|
95
|
-
|
96
|
-
- 22
|
97
|
-
version: 2.0.0.beta.22
|
92
|
+
- 1
|
93
|
+
version: 2.0.1
|
98
94
|
name: rspec
|
99
95
|
prerelease: false
|
100
96
|
type: :development
|
@@ -103,7 +99,7 @@ dependencies:
|
|
103
99
|
requirement: &id006 !ruby/object:Gem::Requirement
|
104
100
|
none: false
|
105
101
|
requirements:
|
106
|
-
- -
|
102
|
+
- - ~>
|
107
103
|
- !ruby/object:Gem::Version
|
108
104
|
hash: 35
|
109
105
|
segments:
|
@@ -119,7 +115,7 @@ dependencies:
|
|
119
115
|
requirement: &id007 !ruby/object:Gem::Requirement
|
120
116
|
none: false
|
121
117
|
requirements:
|
122
|
-
- -
|
118
|
+
- - ~>
|
123
119
|
- !ruby/object:Gem::Version
|
124
120
|
hash: 7
|
125
121
|
segments:
|
@@ -163,6 +159,7 @@ files:
|
|
163
159
|
- lib/rails_best_practices/checks/use_observer_check.rb
|
164
160
|
- lib/rails_best_practices/checks/check.rb
|
165
161
|
- lib/rails_best_practices/checks/overuse_route_customizations_check.rb
|
162
|
+
- lib/rails_best_practices/checks/use_query_attribute_check.rb
|
166
163
|
- lib/rails_best_practices/checks/use_before_filter_check.rb
|
167
164
|
- lib/rails_best_practices/checks/move_code_into_model_check.rb
|
168
165
|
- lib/rails_best_practices/core.rb
|