rails_best_practices 0.3.3 → 0.3.4

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/README.textile CHANGED
@@ -22,7 +22,7 @@ sudo gem install rails_best_practices --source http://gemcutter.org
22
22
 
23
23
  h2. Usage
24
24
 
25
- at the root directory of rails app
25
+ At the root directory of rails app
26
26
 
27
27
  <pre><code>
28
28
  rails_best_practices .
@@ -45,6 +45,18 @@ Usage: rails_best_practices [options]
45
45
 
46
46
  *************************************************
47
47
 
48
+ h2. Issue
49
+
50
+ If you got NoMethodError or any syntax error, you should use debug mode to detect which file rails_best_practices is parsing and getting the error.
51
+
52
+ <pre><code>
53
+ rails_best_practices -d .
54
+ </code></pre>
55
+
56
+ Then give me the error stack and the source code of the file that rails_best_practices is parsing error.
57
+
58
+ *************************************************
59
+
48
60
  h2. Customize Configuration
49
61
 
50
62
  Copy <code>rails_best_practices.yml</code> in the root directory of rails_best_practices gem to <code>config</code> directory
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.4
@@ -21,11 +21,15 @@ module RailsBestPractices
21
21
  def initialize
22
22
  super
23
23
  @files = []
24
- @references = {}
25
- @indexes = {}
24
+ @@indexes = {}
26
25
  @parse = false
27
26
  end
28
27
 
28
+ # make indexes class method for get indexes out of AlwaysAddDbIndexCheck class.
29
+ def self.indexes
30
+ @@indexes
31
+ end
32
+
29
33
  def evaluate_start(node)
30
34
  if @files.include? node.file
31
35
  @parse = true if :up == node.message
@@ -34,57 +38,63 @@ module RailsBestPractices
34
38
  end
35
39
 
36
40
  if @parse and :up == node.message
37
- @references.each do |table_name, column_names|
38
- differences = column_names - (@indexes[table_name] || [])
39
- @references[table_name] = column_names - differences
40
- hint = differences.collect {|column_name| "#{table_name} => #{column_name}"}.join(', ')
41
- add_error "always add db index (#{hint})" unless differences.empty?
42
- end
41
+ check_references(node.body)
43
42
  else
44
- remember_references(node.body)
45
43
  remember_indexes(node.body)
46
44
  end
47
45
  end
48
46
 
49
47
  private
50
48
 
51
- def remember_references(node)
49
+ def check_references(node)
52
50
  create_table_node = node.grep_nodes({:node_type => :call, :message => :create_table}).first
53
51
  if create_table_node
54
52
  table_name = create_table_node.arguments[1].to_ruby_string
55
53
  node.grep_nodes({:node_type => :call, :message => :integer}).each do |integer_node|
56
54
  column_name = integer_node.arguments[1].to_ruby_string
57
- if column_name =~ /_id$/
58
- @references[table_name] ||= []
59
- @references[table_name] << column_name
55
+ if column_name =~ /_id$/ and !@@indexes[table_name].include? column_name
56
+ add_error "always add db index (#{table_name} => #{column_name})"
60
57
  end
61
58
  end
62
59
  node.grep_nodes({:node_type => :call, :message => :references}).each do |references_node|
63
60
  column_name = references_node.arguments[1].to_ruby_string + "_id"
64
- @references[table_name] ||= []
65
- @references[table_name] << column_name
61
+ if !@@indexes[table_name].include? column_name
62
+ add_error "always add db index (#{table_name} => #{column_name})"
63
+ end
66
64
  end
67
65
  node.grep_nodes({:node_type => :call, :message => :column}).each do |column_node|
68
66
  if 'integer' == column_node.arguments[2].to_ruby_string
69
67
  column_name = column_node.arguments[1].to_ruby_string
70
- if column_name =~ /_id$/
71
- @references[table_name] ||= []
72
- @references[table_name] << column_name
68
+ if column_name =~ /_id$/ and !@@indexes[table_name].include? column_name
69
+ add_error "always add db index (#{table_name} => #{column_name})"
73
70
  end
74
71
  end
75
72
  end
76
73
  end
77
74
  end
78
75
 
79
- def remember_indexes(node)
80
- add_index_nodes = node.grep_nodes({:node_type => :call, :message => :add_index})
81
- add_index_nodes.each do |add_index_node|
82
- table_name = add_index_node.arguments[1].to_ruby_string
83
- column_name = add_index_node.arguments[2].to_ruby_string
84
- @indexes[table_name] ||= []
85
- @indexes[table_name] << column_name
76
+ # dynamically execute add_index because static parser can't handle
77
+ #
78
+ # [[:comments, :post_id], [:comments, :user_id]].each do |args|
79
+ # add_index *args
80
+ # end
81
+ def remember_indexes(nodes)
82
+ nodes.each do |node|
83
+ begin
84
+ eval(node.to_ruby)
85
+ rescue
86
+ end
86
87
  end
87
88
  end
88
89
  end
89
90
  end
90
91
  end
92
+
93
+ def add_index(*args)
94
+ table_name, column_names = *args
95
+ table_name = table_name.to_s
96
+ RailsBestPractices::Checks::AlwaysAddDbIndexCheck.indexes[table_name] ||= []
97
+ Array(column_names).each do |column_name|
98
+ RailsBestPractices::Checks::AlwaysAddDbIndexCheck.indexes[table_name] << column_name.to_s
99
+ end
100
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rails_best_practices}
8
- s.version = "0.3.3"
8
+ s.version = "0.3.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Richard Huang"]
12
- s.date = %q{2009-11-19}
12
+ s.date = %q{2009-11-22}
13
13
  s.default_executable = %q{rails_best_practices}
14
14
  s.description = %q{check rails files according to ihower's presentation 'rails best practices'}
15
15
  s.email = %q{flyerhzm@gmail.com}
@@ -88,27 +88,27 @@ Gem::Specification.new do |s|
88
88
  s.rubygems_version = %q{1.3.5}
89
89
  s.summary = %q{check rails files according to ihower's presentation 'rails best practices'}
90
90
  s.test_files = [
91
- "spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb",
92
- "spec/rails_best_practices/checks/always_add_db_index_check_spec.rb",
93
- "spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
94
- "spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
95
- "spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
96
- "spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
97
- "spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
98
- "spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
99
- "spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
91
+ "spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
100
92
  "spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb",
101
- "spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
102
- "spec/rails_best_practices/checks/nested_model_forms_check_spec.rb",
103
- "spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
93
+ "spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
94
+ "spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
95
+ "spec/rails_best_practices/checks/use_observer_check_spec.rb",
104
96
  "spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb",
97
+ "spec/rails_best_practices/checks/nested_model_forms_check_spec.rb",
98
+ "spec/rails_best_practices/checks/always_add_db_index_check_spec.rb",
99
+ "spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
100
+ "spec/rails_best_practices/checks/use_before_filter_check_spec.rb",
101
+ "spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
102
+ "spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
105
103
  "spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
104
+ "spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
105
+ "spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
106
+ "spec/rails_best_practices/checks/use_model_callback_check_spec.rb",
107
+ "spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb",
106
108
  "spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb",
107
- "spec/rails_best_practices/checks/use_before_filter_check_spec.rb",
108
109
  "spec/rails_best_practices/checks/use_model_association_check_spec.rb",
109
- "spec/rails_best_practices/checks/use_model_callback_check_spec.rb",
110
- "spec/rails_best_practices/checks/use_observer_check_spec.rb",
111
- "spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
110
+ "spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
111
+ "spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
112
112
  "spec/spec_helper.rb"
113
113
  ]
114
114
 
@@ -25,7 +25,8 @@ describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
25
25
  @runner.check('db/migrate/20090918130258_create_comments.rb', content)
26
26
  errors = @runner.errors
27
27
  errors.should_not be_empty
28
- errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
28
+ errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id)"
29
+ errors[1].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => user_id)"
29
30
  end
30
31
 
31
32
  it "should always add db index with column has no id" do
@@ -69,7 +70,8 @@ describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
69
70
  @runner.check('db/migrate/20090918130258_create_comments.rb', content)
70
71
  errors = @runner.errors
71
72
  errors.should_not be_empty
72
- errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
73
+ errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id)"
74
+ errors[1].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => user_id)"
73
75
  end
74
76
 
75
77
  it "should always add db index with column" do
@@ -92,7 +94,8 @@ describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
92
94
  @runner.check('db/migrate/20090918130258_create_comments.rb', content)
93
95
  errors = @runner.errors
94
96
  errors.should_not be_empty
95
- errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
97
+ errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id)"
98
+ errors[1].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => user_id)"
96
99
  end
97
100
 
98
101
  it "should not always add db index with add_index" do
@@ -145,9 +148,33 @@ describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
145
148
  end
146
149
  EOF
147
150
  @runner.check('db/migrate/20090918130258_create_comments.rb', content)
148
- @runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', content)
151
+ @runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', add_index_content)
149
152
  @runner.check('db/migrate/20090918130258_create_comments.rb', content)
150
- @runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', content)
153
+ @runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', add_index_content)
154
+ errors = @runner.errors
155
+ errors.should be_empty
156
+ end
157
+
158
+ it "should always add db index without error" do
159
+ content = <<-EOF
160
+ class AddIndexes < ActiveRecord::Migration
161
+ def self.up
162
+ [[:site_wide_admins, :admin_id, { :unique => true }],
163
+ [:photos, [:target_id, :target_type, :type]],
164
+ [:photos, [:target_id, :target_type, :parent_id, :is_avatar]],
165
+ [:category_assignments, [:category_id, :sub_category_id, :target_id, :target_type]],
166
+ [:network_connections, :user_id]].each do |args|
167
+ add_index(*args) rescue say "Failed to add index"
168
+ end
169
+ # raise "abort migration"
170
+ end
171
+
172
+ def self.down
173
+ end
174
+ end
175
+ EOF
176
+ @runner.check('db/migrate/20091111113612_add_indexes.rb', content)
177
+ @runner.check('db/migrate/20091111113612_add_indexes.rb', content)
151
178
  errors = @runner.errors
152
179
  end
153
180
  end
@@ -5,7 +5,7 @@ describe RailsBestPractices::Checks::UseBeforeFilterCheck do
5
5
  @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::UseBeforeFilterCheck.new)
6
6
  end
7
7
 
8
- it "should use filter" do
8
+ it "should use before_filter" do
9
9
  content = <<-EOF
10
10
  class PostsController < ApplicationController
11
11
 
@@ -32,10 +32,10 @@ describe RailsBestPractices::Checks::UseBeforeFilterCheck do
32
32
  @runner.check('app/controllers/posts_controller.rb', content)
33
33
  errors = @runner.errors
34
34
  errors.should_not be_empty
35
- errors[0].to_s.should == "app/controllers/posts_controller.rb:1 - use filter for @post = current_user.posts.find(params[:id]) in show,edit,update,destroy"
35
+ errors[0].to_s.should == "app/controllers/posts_controller.rb:1 - use before_filter for @post = current_user.posts.find(params[:id]) in show,edit,update,destroy"
36
36
  end
37
37
 
38
- it "should not use filter" do
38
+ it "should not use before_filter" do
39
39
  content = <<-EOF
40
40
  class PostsController < ApplicationController
41
41
  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
@@ -60,7 +60,7 @@ describe RailsBestPractices::Checks::UseBeforeFilterCheck do
60
60
  errors.should be_empty
61
61
  end
62
62
 
63
- it "should not use filter by nil" do
63
+ it "should not use before_filter by nil" do
64
64
  content = <<-EOF
65
65
  class PostsController < ApplicationController
66
66
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_best_practices
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-19 00:00:00 +08:00
12
+ date: 2009-11-22 00:00:00 +08:00
13
13
  default_executable: rails_best_practices
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -133,25 +133,25 @@ signing_key:
133
133
  specification_version: 3
134
134
  summary: check rails files according to ihower's presentation 'rails best practices'
135
135
  test_files:
136
- - spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb
137
- - spec/rails_best_practices/checks/always_add_db_index_check_spec.rb
138
136
  - spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb
139
- - spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb
140
- - spec/rails_best_practices/checks/law_of_demeter_check_spec.rb
141
- - spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb
142
- - spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb
143
- - spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb
144
- - spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb
145
137
  - spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb
146
- - spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb
147
- - spec/rails_best_practices/checks/nested_model_forms_check_spec.rb
148
- - spec/rails_best_practices/checks/not_use_default_route_check_spec.rb
138
+ - spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb
139
+ - spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb
140
+ - spec/rails_best_practices/checks/use_observer_check_spec.rb
149
141
  - spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb
142
+ - spec/rails_best_practices/checks/nested_model_forms_check_spec.rb
143
+ - spec/rails_best_practices/checks/always_add_db_index_check_spec.rb
144
+ - spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb
145
+ - spec/rails_best_practices/checks/use_before_filter_check_spec.rb
146
+ - spec/rails_best_practices/checks/law_of_demeter_check_spec.rb
147
+ - spec/rails_best_practices/checks/use_scope_access_check_spec.rb
150
148
  - spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb
149
+ - spec/rails_best_practices/checks/not_use_default_route_check_spec.rb
150
+ - spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb
151
+ - spec/rails_best_practices/checks/use_model_callback_check_spec.rb
152
+ - spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb
151
153
  - spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb
152
- - spec/rails_best_practices/checks/use_before_filter_check_spec.rb
153
154
  - spec/rails_best_practices/checks/use_model_association_check_spec.rb
154
- - spec/rails_best_practices/checks/use_model_callback_check_spec.rb
155
- - spec/rails_best_practices/checks/use_observer_check_spec.rb
156
- - spec/rails_best_practices/checks/use_scope_access_check_spec.rb
155
+ - spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb
156
+ - spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb
157
157
  - spec/spec_helper.rb