bullet 5.5.1 → 5.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '06945d7fd724e3e1f6355de32b078fac99e6366a'
4
- data.tar.gz: ab28a1e628416d945ec40ad21b0ff3e8e4dd50ac
3
+ metadata.gz: 652f59b5a91224c16cace3931e368d0da02fa449
4
+ data.tar.gz: 9ef371969315cd308b194a9d230d1f19892a57e4
5
5
  SHA512:
6
- metadata.gz: 33e0206bd7d7624e3ca311f48274708fcc8030a23ec77954007faaa6b2b14b1d4fd3a7f75c18a8150399565770dd19e252856c2cc94907c6abd3147488280bbf
7
- data.tar.gz: cac678c258a0d278c92cbff1bb5e820d9ec71d628a55573588d3fb100a2ded60d28e496c7906632d438f367835d41b923aa98828028693183610840a22c5d114
6
+ metadata.gz: ed473ab951e1f168de703cf0615f203abc93e37ef896330d6f91c7b61d320cd0906e691e41245e13a11aa9e3aa3d059ea62b00b256fa96af0540c8ab35ebc2fb
7
+ data.tar.gz: f6c4456dfb56957b441fce1b56094baacc911186b59b48b43f22e41ad3bbed88c52aa16b4bc7247b7ca37a3c7d026bb45f5342ccc24b37bc47836cd63fb41a1c
@@ -8,10 +8,5 @@ gemfile:
8
8
  - Gemfile.rails-4.2
9
9
  - Gemfile.rails-4.1
10
10
  - Gemfile.rails-4.0
11
- - Gemfile.mongoid-6.0
12
- - Gemfile.mongoid-5.0
13
- - Gemfile.mongoid-4.0
14
11
  env:
15
12
  - DB=sqlite
16
- services:
17
- - mongodb
@@ -1,10 +1,13 @@
1
1
  # Next Release
2
2
 
3
- ## 5.5.1 (03/01/2016)
3
+ ## 5.6.0 (07/16/2017)
4
4
 
5
+ * Migrate alias_method to Module#prepend
6
+ * Add install generator
7
+ * Stack trace filter
8
+ * Fix rails 5.1 compatibility
5
9
  * Fix inverse_of for rails 5
6
10
  * Fix detect file attachment for rack #319
7
- * Fix `ActiveRecord::Associations::SingularAssociation#reader` usage for Rails 5.1
8
11
 
9
12
  ## 5.5.0 (12/30/2016)
10
13
 
data/Gemfile CHANGED
@@ -1,8 +1,13 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
3
8
  gemspec
4
9
 
5
- gem 'rails', github: 'rails/rails'
10
+ gem 'rails', github: 'rails'
6
11
  gem 'sqlite3', platforms: [:ruby]
7
12
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
13
  gem 'activerecord-import'
@@ -2,7 +2,7 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '5.0.0'
5
+ gem 'rails', '~> 5.0.0'
6
6
  gem 'sqlite3'
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
@@ -2,7 +2,7 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '5.1.0.beta.1'
5
+ gem 'rails', '~> 5.1.0'
6
6
  gem 'sqlite3'
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
data/README.md CHANGED
@@ -303,19 +303,10 @@ And run
303
303
  bundle install
304
304
  ```
305
305
 
306
- 6\. enable the Bullet gem in development, add a line to
307
- `config/environments/development.rb`
306
+ 6\. enable the Bullet gem with generate command
308
307
 
309
- ```ruby
310
- config.after_initialize do
311
- Bullet.enable = true
312
- Bullet.alert = true
313
- Bullet.bullet_logger = true
314
- Bullet.console = true
315
- # Bullet.growl = true
316
- Bullet.rails_logger = true
317
- Bullet.add_footer = true
318
- end
308
+ ```
309
+ bundle exec rails g bullet:install
319
310
  ```
320
311
 
321
312
  7\. Start the server
@@ -18,38 +18,34 @@ module Bullet
18
18
  module ActiveRecord
19
19
  def self.enable
20
20
  require 'active_record'
21
- ::ActiveRecord::Base.class_eval do
22
- class <<self
23
- alias_method :origin_find_by_sql, :find_by_sql
24
- def find_by_sql(sql, binds = [], preparable: nil, &block)
25
- result = origin_find_by_sql(sql, binds, preparable: nil, &block)
26
- if Bullet.start?
27
- if result.is_a? Array
28
- if result.size > 1
29
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
30
- Bullet::Detector::CounterCache.add_possible_objects(result)
31
- elsif result.size == 1
32
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
33
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
34
- end
35
- elsif result.is_a? ::ActiveRecord::Base
36
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
37
- Bullet::Detector::CounterCache.add_impossible_object(result)
21
+ ::ActiveRecord::Base.extend(Module.new {
22
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
23
+ result = super
24
+ if Bullet.start?
25
+ if result.is_a? Array
26
+ if result.size > 1
27
+ Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
28
+ Bullet::Detector::CounterCache.add_possible_objects(result)
29
+ elsif result.size == 1
30
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
31
+ Bullet::Detector::CounterCache.add_impossible_object(result.first)
38
32
  end
33
+ elsif result.is_a? ::ActiveRecord::Base
34
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
35
+ Bullet::Detector::CounterCache.add_impossible_object(result)
39
36
  end
40
- result
41
37
  end
38
+ result
42
39
  end
43
- end
40
+ })
44
41
 
45
42
  ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
46
43
 
47
- ::ActiveRecord::Relation.class_eval do
48
- alias_method :origin_records, :records
44
+ ::ActiveRecord::Relation.prepend(Module.new {
49
45
  # if select a collection of objects, then these objects have possible to cause N+1 query.
50
46
  # if select only one object, then the only one object has impossible to cause N+1 query.
51
47
  def records
52
- result = origin_records
48
+ result = super
53
49
  if Bullet.start?
54
50
  if result.first.class.name !~ /^HABTM_/
55
51
  if result.size > 1
@@ -63,11 +59,9 @@ module Bullet
63
59
  end
64
60
  result
65
61
  end
66
- end
67
-
68
- ::ActiveRecord::Associations::Preloader.class_eval do
69
- alias_method :origin_preloaders_for_one, :preloaders_for_one
62
+ })
70
63
 
64
+ ::ActiveRecord::Associations::Preloader.prepend(Module.new {
71
65
  def preloaders_for_one(association, records, scope)
72
66
  if Bullet.start?
73
67
  records.compact!
@@ -78,16 +72,15 @@ module Bullet
78
72
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
79
73
  end
80
74
  end
81
- origin_preloaders_for_one(association, records, scope)
75
+ super
82
76
  end
83
- end
77
+ })
84
78
 
85
- ::ActiveRecord::FinderMethods.class_eval do
79
+ ::ActiveRecord::FinderMethods.prepend(Module.new {
86
80
  # add includes in scope
87
- alias_method :origin_find_with_associations, :find_with_associations
88
81
  def find_with_associations
89
- return origin_find_with_associations { |r| yield r } if block_given?
90
- records = origin_find_with_associations
82
+ return super { |r| yield r } if block_given?
83
+ records = super
91
84
  if Bullet.start?
92
85
  associations = (eager_load_values + includes_values).uniq
93
86
  records.each do |record|
@@ -97,16 +90,12 @@ module Bullet
97
90
  end
98
91
  records
99
92
  end
100
- end
101
-
102
- ::ActiveRecord::Associations::JoinDependency.class_eval do
103
- alias_method :origin_instantiate, :instantiate
104
- alias_method :origin_construct, :construct
105
- alias_method :origin_construct_model, :construct_model
93
+ })
106
94
 
95
+ ::ActiveRecord::Associations::JoinDependency.prepend(Module.new {
107
96
  def instantiate(result_set, aliases)
108
97
  @bullet_eager_loadings = {}
109
- records = origin_instantiate(result_set, aliases)
98
+ records = super
110
99
 
111
100
  if Bullet.start?
112
101
  @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
@@ -135,12 +124,12 @@ module Bullet
135
124
  end
136
125
  end
137
126
 
138
- origin_construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
127
+ super
139
128
  end
140
129
 
141
130
  # call join associations
142
131
  def construct_model(record, node, row, model_cache, id, aliases)
143
- result = origin_construct_model(record, node, row, model_cache, id, aliases)
132
+ result = super
144
133
 
145
134
  if Bullet.start?
146
135
  associations = node.reflection.name
@@ -153,13 +142,11 @@ module Bullet
153
142
 
154
143
  result
155
144
  end
156
- end
145
+ })
157
146
 
158
- ::ActiveRecord::Associations::CollectionAssociation.class_eval do
159
- # call one to many associations
160
- alias_method :origin_load_target, :load_target
147
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(Module.new {
161
148
  def load_target
162
- records = origin_load_target
149
+ records = super
163
150
 
164
151
  if Bullet.start?
165
152
  if self.is_a? ::ActiveRecord::Associations::ThroughAssociation
@@ -183,28 +170,25 @@ module Bullet
183
170
  records
184
171
  end
185
172
 
186
- alias_method :origin_empty?, :empty?
187
173
  def empty?
188
174
  if Bullet.start? && !reflection.has_cached_counter?
189
175
  Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
190
176
  end
191
- origin_empty?
177
+ super
192
178
  end
193
179
 
194
- alias_method :origin_include?, :include?
195
180
  def include?(object)
196
181
  if Bullet.start?
197
182
  Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
198
183
  end
199
- origin_include?(object)
184
+ super
200
185
  end
201
- end
186
+ })
202
187
 
203
- ::ActiveRecord::Associations::SingularAssociation.class_eval do
188
+ ::ActiveRecord::Associations::SingularAssociation.prepend(Module.new {
204
189
  # call has_one and belongs_to associations
205
- alias_method :origin_reader, :reader
206
- def reader(force_reload = false)
207
- result = force_reload ? force_reload_reader : origin_reader
190
+ def target
191
+ result = super()
208
192
  if Bullet.start?
209
193
  if owner.class.name !~ /^HABTM_/ && !@inversed
210
194
  Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
@@ -217,27 +201,25 @@ module Bullet
217
201
  end
218
202
  result
219
203
  end
220
- end
204
+ })
221
205
 
222
- ::ActiveRecord::Associations::HasManyAssociation.class_eval do
223
- alias_method :origin_many_empty?, :empty?
206
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(Module.new {
224
207
  def empty?
225
- result = origin_many_empty?
208
+ result = super
226
209
  if Bullet.start? && !reflection.has_cached_counter?
227
210
  Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
228
211
  end
229
212
  result
230
213
  end
231
214
 
232
- alias_method :origin_count_records, :count_records
233
215
  def count_records
234
216
  result = reflection.has_cached_counter?
235
217
  if Bullet.start? && !result && !self.is_a?(::ActiveRecord::Associations::ThroughAssociation)
236
218
  Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
237
219
  end
238
- origin_count_records
220
+ super
239
221
  end
240
- end
222
+ })
241
223
  end
242
224
  end
243
225
  end
@@ -7,7 +7,7 @@ module Bullet
7
7
  return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
8
8
  return unless object.primary_key_value
9
9
 
10
- Bullet.debug("Detector::Association#add_object_associations", "object: #{object.bullet_key}, associations: #{associations}")
10
+ Bullet.debug("Detector::Association#add_object_associations".freeze, "object: #{object.bullet_key}, associations: #{associations}")
11
11
  object_associations.add(object.bullet_key, associations)
12
12
  end
13
13
 
@@ -16,7 +16,7 @@ module Bullet
16
16
  return if !Bullet.n_plus_one_query_enable? && !Bullet.unused_eager_loading_enable?
17
17
  return unless object.primary_key_value
18
18
 
19
- Bullet.debug("Detector::Association#add_call_object_associations", "object: #{object.bullet_key}, associations: #{associations}")
19
+ Bullet.debug("Detector::Association#add_call_object_associations".freeze, "object: #{object.bullet_key}, associations: #{associations}")
20
20
  call_object_associations.add(object.bullet_key, associations)
21
21
  end
22
22
 
@@ -16,7 +16,7 @@ module Bullet
16
16
  return if inversed_objects.include?(object.bullet_key, associations)
17
17
  add_call_object_associations(object, associations)
18
18
 
19
- Bullet.debug("Detector::NPlusOneQuery#call_association", "object: #{object.bullet_key}, associations: #{associations}")
19
+ Bullet.debug("Detector::NPlusOneQuery#call_association".freeze, "object: #{object.bullet_key}, associations: #{associations}")
20
20
  if !excluded_stacktrace_path? && conditions_met?(object, associations)
21
21
  Bullet.debug("detect n + 1 query", "object: #{object.bullet_key}, associations: #{associations}")
22
22
  create_notification caller_in_project, object.class.to_s, associations
@@ -29,7 +29,7 @@ module Bullet
29
29
  objects = Array(object_or_objects)
30
30
  return if objects.map(&:primary_key_value).compact.empty?
31
31
 
32
- Bullet.debug("Detector::NPlusOneQuery#add_possible_objects", "objects: #{objects.map(&:bullet_key).join(', ')}")
32
+ Bullet.debug("Detector::NPlusOneQuery#add_possible_objects".freeze, "objects: #{objects.map(&:bullet_key).join(', '.freeze)}")
33
33
  objects.each { |object| possible_objects.add object.bullet_key }
34
34
  end
35
35
 
@@ -38,7 +38,7 @@ module Bullet
38
38
  return unless Bullet.n_plus_one_query_enable?
39
39
  return unless object.primary_key_value
40
40
 
41
- Bullet.debug("Detector::NPlusOneQuery#add_impossible_object", "object: #{object.bullet_key}")
41
+ Bullet.debug("Detector::NPlusOneQuery#add_impossible_object".freeze, "object: #{object.bullet_key}")
42
42
  impossible_objects.add object.bullet_key
43
43
  end
44
44
 
@@ -47,7 +47,7 @@ module Bullet
47
47
  return unless Bullet.n_plus_one_query_enable?
48
48
  return unless object.primary_key_value
49
49
 
50
- Bullet.debug("Detector::NPlusOneQuery#add_inversed_object", "object: #{object.bullet_key}, association: #{association}")
50
+ Bullet.debug("Detector::NPlusOneQuery#add_inversed_object".freeze, "object: #{object.bullet_key}, association: #{association}")
51
51
  inversed_objects.add object.bullet_key, association
52
52
  end
53
53
 
@@ -5,7 +5,7 @@ class Object
5
5
 
6
6
  def primary_key_value
7
7
  if self.class.respond_to?(:primary_keys) && self.class.primary_keys
8
- self.class.primary_keys.map { |primary_key| self.send primary_key }.join(',')
8
+ self.class.primary_keys.map { |primary_key| self.send primary_key }.join(','.freeze)
9
9
  elsif self.class.respond_to?(:primary_key) && self.class.primary_key
10
10
  self.send self.class.primary_key
11
11
  else
@@ -1,5 +1,5 @@
1
1
  class String
2
2
  def bullet_class_name
3
- self.sub(/:[^:]*?$/, "")
3
+ self.sub(/:[^:]*?$/, "".freeze)
4
4
  end
5
5
  end
@@ -66,7 +66,7 @@ module Bullet
66
66
 
67
67
  protected
68
68
  def klazz_associations_str
69
- " #{@base_class} => [#{@associations.map(&:inspect).join(', ')}]"
69
+ " #{@base_class} => [#{@associations.map(&:inspect).join(', '.freeze)}]"
70
70
  end
71
71
 
72
72
  def associations_str
@@ -5,7 +5,8 @@ module Bullet
5
5
  def caller_in_project
6
6
  app_root = rails? ? Rails.root.to_s : Dir.pwd
7
7
  vendor_root = app_root + VENDOR_PATH
8
- caller.select do |caller_path|
8
+ caller_locations.select do |location|
9
+ caller_path = location.absolute_path
9
10
  caller_path.include?(app_root) && !caller_path.include?(vendor_root) ||
10
11
  Bullet.stacktrace_includes.any? do |include_pattern|
11
12
  case include_pattern
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Bullet
3
- VERSION = "5.5.1"
3
+ VERSION = "5.6.0"
4
4
  end
@@ -0,0 +1,46 @@
1
+ module Bullet
2
+ module Generators
3
+ class InstallGenerator < ::Rails::Generators::Base
4
+ desc <<-DESC
5
+ Description:
6
+ Enable bullet in development/test for your application.
7
+ DESC
8
+
9
+ def enable_in_development
10
+ environment(nil, env: "development") do
11
+ <<-"FILE".strip
12
+
13
+ config.after_initialize do
14
+ Bullet.enable = true
15
+ Bullet.alert = true
16
+ Bullet.bullet_logger = true
17
+ Bullet.console = true
18
+ # Bullet.growl = true
19
+ Bullet.rails_logger = true
20
+ Bullet.add_footer = true
21
+ end
22
+ FILE
23
+ end
24
+
25
+ say "Enabled bullet in config/environments/development.rb"
26
+ end
27
+
28
+ def enable_in_test
29
+ if yes?("Would you like to enable bullet in test environment? (y/n)")
30
+ environment(nil, env: "test") do
31
+ <<-"FILE".strip
32
+
33
+ config.after_initialize do
34
+ Bullet.enable = true
35
+ Bullet.bullet_logger = true
36
+ Bullet.raise = true # raise an error if n+1 query occurs
37
+ end
38
+ FILE
39
+ end
40
+
41
+ say "Enabled bullet in config/environments/test.rb"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -91,11 +91,11 @@ module Bullet
91
91
  after { Bullet.stacktrace_excludes = nil }
92
92
 
93
93
  it "should not create notification when stacktrace contains paths that are in the exclude list" do
94
- in_project = File.join(Dir.pwd, 'abc', 'abc.rb')
95
- included_path = '/ghi/ghi.rb'
96
- excluded_path = '/def/def.rb'
94
+ in_project = OpenStruct.new(:absolute_path => File.join(Dir.pwd, 'abc', 'abc.rb'))
95
+ included_path = OpenStruct.new(:absolute_path => '/ghi/ghi.rb')
96
+ excluded_path = OpenStruct.new(:absolute_path => '/def/def.rb')
97
97
 
98
- expect(NPlusOneQuery).to receive(:caller).and_return([in_project, included_path, excluded_path])
98
+ expect(NPlusOneQuery).to receive(:caller_locations).and_return([in_project, included_path, excluded_path])
99
99
  expect(NPlusOneQuery).to_not receive(:create_notification)
100
100
  NPlusOneQuery.call_association(@post, :association)
101
101
  end
@@ -104,10 +104,10 @@ module Bullet
104
104
 
105
105
  context ".caller_in_project" do
106
106
  it "should include only paths that are in the project" do
107
- in_project = File.join(Dir.pwd, 'abc', 'abc.rb')
108
- not_in_project = '/def/def.rb'
107
+ in_project = OpenStruct.new(:absolute_path => File.join(Dir.pwd, 'abc', 'abc.rb'))
108
+ not_in_project = OpenStruct.new(:absolute_path => '/def/def.rb')
109
109
 
110
- expect(NPlusOneQuery).to receive(:caller).and_return([in_project, not_in_project])
110
+ expect(NPlusOneQuery).to receive(:caller_locations).and_return([in_project, not_in_project])
111
111
  expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
112
112
  expect(NPlusOneQuery).to receive(:create_notification).with([in_project], "Post", :association)
113
113
  NPlusOneQuery.call_association(@post, :association)
@@ -118,11 +118,11 @@ module Bullet
118
118
  after { Bullet.stacktrace_includes = nil }
119
119
 
120
120
  it "should include paths that are in the stacktrace_include list" do
121
- in_project = File.join(Dir.pwd, 'abc', 'abc.rb')
122
- included_gems = ['/def/def.rb', 'xyz/xyz.rb']
123
- excluded_gem = '/ghi/ghi.rb'
121
+ in_project = OpenStruct.new(:absolute_path => File.join(Dir.pwd, 'abc', 'abc.rb'))
122
+ included_gems = [OpenStruct.new(:absolute_path => '/def/def.rb'), OpenStruct.new(:absolute_path => 'xyz/xyz.rb')]
123
+ excluded_gem = OpenStruct.new(:absolute_path => '/ghi/ghi.rb')
124
124
 
125
- expect(NPlusOneQuery).to receive(:caller).and_return([in_project, *included_gems, excluded_gem])
125
+ expect(NPlusOneQuery).to receive(:caller_locations).and_return([in_project, *included_gems, excluded_gem])
126
126
  expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
127
127
  expect(NPlusOneQuery).to receive(:create_notification).with([in_project, *included_gems], "Post", :association)
128
128
  NPlusOneQuery.call_association(@post, :association)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.1
4
+ version: 5.6.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: 2017-03-01 00:00:00.000000000 Z
11
+ date: 2017-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -95,6 +95,7 @@ files:
95
95
  - lib/bullet/registry/object.rb
96
96
  - lib/bullet/stack_trace_filter.rb
97
97
  - lib/bullet/version.rb
98
+ - lib/generators/bullet/install_generator.rb
98
99
  - perf/benchmark.rb
99
100
  - rails/init.rb
100
101
  - spec/bullet/detector/association_spec.rb
@@ -177,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
178
  version: 1.3.6
178
179
  requirements: []
179
180
  rubyforge_project:
180
- rubygems_version: 2.5.2
181
+ rubygems_version: 2.6.12
181
182
  signing_key:
182
183
  specification_version: 4
183
184
  summary: help to kill N+1 queries and unused eager loading.