bullet 2.0.0.beta.2 → 2.1.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.
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rvmrc +2 -0
- data/.rvmrc.example +2 -0
- data/.watchr +24 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +105 -0
- data/Hacking.textile +69 -0
- data/MIT-LICENSE +1 -1
- data/README.textile +61 -49
- data/README_for_rails2.textile +41 -42
- data/Rakefile +40 -29
- data/bullet.gemspec +17 -60
- data/lib/bullet/action_controller2.rb +6 -6
- data/lib/bullet/active_record2.rb +17 -16
- data/lib/bullet/active_record3.rb +17 -25
- data/lib/bullet/active_record31.rb +96 -0
- data/lib/bullet/detector/association.rb +144 -0
- data/lib/bullet/detector/base.rb +12 -0
- data/lib/bullet/detector/counter.rb +43 -0
- data/lib/bullet/detector/n_plus_one_query.rb +39 -0
- data/lib/bullet/detector/unused_eager_association.rb +41 -0
- data/lib/bullet/detector.rb +9 -0
- data/lib/bullet/notification/base.rb +61 -0
- data/lib/bullet/notification/counter_cache.rb +13 -0
- data/lib/bullet/notification/n_plus_one_query.rb +32 -0
- data/lib/bullet/notification/unused_eager_loading.rb +14 -0
- data/lib/bullet/notification.rb +4 -79
- data/lib/bullet/notification_collector.rb +25 -0
- data/lib/bullet/rack.rb +44 -0
- data/lib/bullet/registry/association.rb +15 -0
- data/lib/bullet/registry/base.rb +37 -0
- data/lib/bullet/registry/object.rb +15 -0
- data/lib/bullet/registry.rb +7 -0
- data/lib/bullet/version.rb +5 -0
- data/lib/bullet.rb +64 -43
- data/perf/benchmark.rb +106 -0
- data/spec/bullet/association_for_chris_spec.rb +6 -6
- data/spec/bullet/association_for_peschkaj_spec.rb +6 -6
- data/spec/bullet/association_spec.rb +140 -294
- data/spec/bullet/counter_spec.rb +10 -10
- data/spec/spec_helper.rb +51 -17
- metadata +72 -57
- data/VERSION +0 -1
- data/lib/bullet/association.rb +0 -294
- data/lib/bullet/counter.rb +0 -101
- data/lib/bullet/logger.rb +0 -9
- data/lib/bulletware.rb +0 -42
- data/spec/spec.opts +0 -3
data/README_for_rails2.textile
CHANGED
|
@@ -6,8 +6,6 @@ Best practice is to use Bullet in development mode or custom mode (staging, prof
|
|
|
6
6
|
|
|
7
7
|
The Bullet plugin/gem now supports rails 2.1, 2.2 and 2.3, tested in rails 2.1.2, 2.2.2 and 2.3.2.
|
|
8
8
|
|
|
9
|
-
*Important: bullet gem has been moved to gemcutter.org*
|
|
10
|
-
|
|
11
9
|
****************************************************************************
|
|
12
10
|
|
|
13
11
|
h2. Change
|
|
@@ -18,6 +16,7 @@ There is a large refactor from gem 1.4 to 1.5, so if you upgrade to 1.5 gem, ple
|
|
|
18
16
|
|
|
19
17
|
h2. Contributors
|
|
20
18
|
|
|
19
|
+
sriedel did a lot of awesome refactors, added xmpp notification support, and added Hacking.textile about how to extend to bullet plugin.
|
|
21
20
|
flipsasser added Growl, console.log and Rails.log support, very awesome. And he also improved README.
|
|
22
21
|
rainux added group style console.log.
|
|
23
22
|
2collegebums added some great specs to generate red bar.
|
|
@@ -26,18 +25,11 @@ rainux added group style console.log.
|
|
|
26
25
|
|
|
27
26
|
h2. Install
|
|
28
27
|
|
|
29
|
-
You can add Bullet to your Rails gem requirements:
|
|
30
|
-
<pre><code>config.gem 'bullet', :source => 'http://gemcutter.org'</code></pre>
|
|
31
|
-
|
|
32
28
|
You can install it as a gem:
|
|
33
29
|
<pre><code>
|
|
34
|
-
sudo gem sources -a http://gemcutter.org
|
|
35
30
|
sudo gem install bullet
|
|
36
31
|
</code></pre>
|
|
37
32
|
|
|
38
|
-
Or you can install it as a rails plugin:
|
|
39
|
-
<pre><code>script/plugin install git://github.com/flyerhzm/bullet.git</code></pre>
|
|
40
|
-
|
|
41
33
|
****************************************************************************
|
|
42
34
|
|
|
43
35
|
h2. Configuration
|
|
@@ -45,24 +37,21 @@ h2. Configuration
|
|
|
45
37
|
Bullet won't do ANYTHING unless you tell it to explicitly. Append to <code>config/environments/development.rb</code> initializer with the following code:
|
|
46
38
|
<pre><code>
|
|
47
39
|
config.after_initialize do
|
|
48
|
-
Bullet.enable = true
|
|
40
|
+
Bullet.enable = true
|
|
49
41
|
Bullet.alert = true
|
|
50
|
-
Bullet.bullet_logger = true
|
|
42
|
+
Bullet.bullet_logger = true
|
|
51
43
|
Bullet.console = true
|
|
52
44
|
Bullet.growl = true
|
|
53
45
|
Bullet.rails_logger = true
|
|
54
46
|
Bullet.disable_browser_cache = true
|
|
47
|
+
Bullet.xmpp = { :account => 'bullets_account@jabber.org',
|
|
48
|
+
:password => 'bullets_password_for_jabber',
|
|
49
|
+
:receiver => 'your_account@jabber.org',
|
|
50
|
+
:show_online_status => true }
|
|
55
51
|
end
|
|
56
52
|
</code></pre>
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
<pre><code>
|
|
60
|
-
begin
|
|
61
|
-
require 'ruby-growl'
|
|
62
|
-
Bullet.growl = true
|
|
63
|
-
rescue MissingSourceFile
|
|
64
|
-
end
|
|
65
|
-
</code></pre>
|
|
54
|
+
The notifier of bullet is a wrap of "uniform_notifier":https://github.com/flyerhzm/uniform_notifier
|
|
66
55
|
|
|
67
56
|
The code above will enable all five of the Bullet notification systems:
|
|
68
57
|
* <code>Bullet.enable</code>: enable Bullet plugin/gem, otherwise do nothing
|
|
@@ -111,10 +100,10 @@ These two lines are notifications that unused eager loadings have been encounter
|
|
|
111
100
|
h2. Growl Support
|
|
112
101
|
|
|
113
102
|
To get Growl support up-and-running for Bullet, follow the steps below:
|
|
114
|
-
* Install the ruby-growl gem: <code>
|
|
103
|
+
* Install the ruby-growl gem: <code>gem install ruby-growl</code>
|
|
115
104
|
* Open the Growl preference pane in Systems Preferences
|
|
116
105
|
* Click the "Network" tab
|
|
117
|
-
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.
|
|
106
|
+
* Make sure both "Listen for incoming notifications" and "Allow remote application registration" are checked. *Note*: If you set a password, you will need to set <code>Bullet.growl = { :password => 'growl password' }</code> in the config file.
|
|
118
107
|
* Restart Growl ("General" tab -> Stop Growl -> Start Growl)
|
|
119
108
|
* Boot up your application. Bullet will automatically send a Growl notification when Growl is turned on. If you do not see it when your application loads, make sure it is enabled in your initializer and double-check the steps above.
|
|
120
109
|
|
|
@@ -126,6 +115,17 @@ ruby-growl gem has an issue about md5 in ruby 1.9, if you use growl and ruby 1.9
|
|
|
126
115
|
|
|
127
116
|
****************************************************************************
|
|
128
117
|
|
|
118
|
+
h2. XMPP/Jabber Support
|
|
119
|
+
|
|
120
|
+
To get XMPP support up-and-running for Bullet, follow the steps below:
|
|
121
|
+
* Install the xmpp4r gem: <code>sudo gem install xmpp4r</code>
|
|
122
|
+
* Make both the bullet and the receipient account add each other as contacts.
|
|
123
|
+
This will require you to manually log into both accounts, add each other
|
|
124
|
+
as contact and confirm each others contact request.
|
|
125
|
+
* Boot up your application. Bullet will automatically send an XMPP notification when XMPP is turned on.
|
|
126
|
+
|
|
127
|
+
****************************************************************************
|
|
128
|
+
|
|
129
129
|
h2. Important
|
|
130
130
|
|
|
131
131
|
If you encounter the following errors in development environment:
|
|
@@ -167,8 +167,7 @@ end
|
|
|
167
167
|
|
|
168
168
|
after(:each)
|
|
169
169
|
if Bullet.enable?
|
|
170
|
-
Bullet.
|
|
171
|
-
Bullet.log_notification('Test: ')
|
|
170
|
+
Bullet.perform_out_of_channel_notifications
|
|
172
171
|
Bullet.end_request
|
|
173
172
|
end
|
|
174
173
|
end
|
|
@@ -193,9 +192,9 @@ Bullet is designed to function as you browse through your application in develop
|
|
|
193
192
|
1. setup test environment
|
|
194
193
|
|
|
195
194
|
<pre><code>
|
|
196
|
-
$ rails
|
|
197
|
-
$ cd
|
|
198
|
-
$ script/generate scaffold post name:string
|
|
195
|
+
$ rails test_bullet
|
|
196
|
+
$ cd test_bullet
|
|
197
|
+
$ script/generate scaffold post name:string
|
|
199
198
|
$ script/generate scaffold comment name:string post_id:integer
|
|
200
199
|
$ rake db:migrate
|
|
201
200
|
</code></pre>
|
|
@@ -280,18 +279,18 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
|
|
|
280
279
|
2009-08-20 09:12:19[INFO] N+1 Query: PATH_INFO: /posts; model: Post => assocations: [comments]
|
|
281
280
|
Add your finder: :include => [:comments]
|
|
282
281
|
2009-08-20 09:12:19[INFO] N+1 Query: method call stack:
|
|
283
|
-
/Users/
|
|
284
|
-
/Users/
|
|
285
|
-
/Users/
|
|
286
|
-
/Users/
|
|
282
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_run_erb_app47views47posts47index46html46erb'
|
|
283
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:8:in `each'
|
|
284
|
+
/Users/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
|
|
285
|
+
/Users/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
|
|
287
286
|
</code></pre>
|
|
288
287
|
|
|
289
288
|
The generated SQLs are
|
|
290
289
|
|
|
291
290
|
<pre><code>
|
|
292
|
-
Post Load (1.0ms) SELECT * FROM "posts"
|
|
293
|
-
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
|
294
|
-
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
|
291
|
+
Post Load (1.0ms) SELECT * FROM "posts"
|
|
292
|
+
Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
|
|
293
|
+
Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
|
|
295
294
|
</code></pre>
|
|
296
295
|
|
|
297
296
|
|
|
@@ -304,8 +303,8 @@ The generated SQLs are
|
|
|
304
303
|
respond_to do |format|
|
|
305
304
|
format.html # index.html.erb
|
|
306
305
|
format.xml { render :xml => @posts }
|
|
307
|
-
end
|
|
308
|
-
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
309
308
|
</code></pre>
|
|
310
309
|
|
|
311
310
|
10. refresh http://localhost:3000/posts page, no alert box and no log appended.
|
|
@@ -313,8 +312,8 @@ The generated SQLs are
|
|
|
313
312
|
The generated SQLs are
|
|
314
313
|
|
|
315
314
|
<pre><code>
|
|
316
|
-
Post Load (0.5ms) SELECT * FROM "posts"
|
|
317
|
-
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
|
315
|
+
Post Load (0.5ms) SELECT * FROM "posts"
|
|
316
|
+
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
|
|
318
317
|
</code></pre>
|
|
319
318
|
|
|
320
319
|
a N+1 query fixed. Cool!
|
|
@@ -328,8 +327,8 @@ a N+1 query fixed. Cool!
|
|
|
328
327
|
respond_to do |format|
|
|
329
328
|
format.html # index.html.erb
|
|
330
329
|
format.xml { render :xml => @posts }
|
|
331
|
-
end
|
|
332
|
-
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
333
332
|
</code></pre>
|
|
334
333
|
|
|
335
334
|
<pre><code>
|
|
@@ -368,8 +367,8 @@ Remove from your finder: :include => [:comments]
|
|
|
368
367
|
respond_to do |format|
|
|
369
368
|
format.html # index.html.erb
|
|
370
369
|
format.xml { render :xml => @posts }
|
|
371
|
-
end
|
|
372
|
-
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
373
372
|
</code></pre>
|
|
374
373
|
|
|
375
374
|
<pre><code>
|
|
@@ -401,4 +400,4 @@ In the meanwhile, there's a log appended into <code>log/bullet.log</code> file.
|
|
|
401
400
|
****************************************************************************
|
|
402
401
|
|
|
403
402
|
|
|
404
|
-
Copyright (c) 2009 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
|
403
|
+
Copyright (c) 2009 - 2011 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
data/Rakefile
CHANGED
|
@@ -1,34 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
require
|
|
3
|
-
|
|
4
|
-
require 'jeweler'
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
|
2
|
+
require "bundler"
|
|
3
|
+
Bundler.setup
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
task
|
|
5
|
+
require "rake"
|
|
6
|
+
require "rdoc/task"
|
|
7
|
+
require "rspec"
|
|
8
|
+
require "rspec/core/rake_task"
|
|
9
|
+
|
|
10
|
+
require "bullet/version"
|
|
11
|
+
|
|
12
|
+
task :build do
|
|
13
|
+
system "gem build bullet.gemspec"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
task :install => :build do
|
|
17
|
+
system "sudo gem install bullet-#{Bullet::VERSION}.gem"
|
|
18
|
+
end
|
|
8
19
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
task :release => :build do
|
|
21
|
+
puts "Tagging #{Bullet::VERSION}..."
|
|
22
|
+
system "git tag -a #{Bullet::VERSION} -m 'Tagging #{Bullet::VERSION}'"
|
|
23
|
+
puts "Pushing to Github..."
|
|
24
|
+
system "git push --tags"
|
|
25
|
+
puts "Pushing to rubygems.org..."
|
|
26
|
+
system "gem push bullet-#{Bullet::VERSION}.gem"
|
|
16
27
|
end
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#Rspec::Core::RakeTask.new(:spec) do |t|
|
|
21
|
-
#t.pattern = FileList['spec/**/*_spec.rb']
|
|
22
|
-
#end
|
|
23
|
-
|
|
24
|
-
Jeweler::Tasks.new do |gemspec|
|
|
25
|
-
gemspec.name = "bullet"
|
|
26
|
-
gemspec.summary = "A plugin to kill N+1 queries and unused eager loading"
|
|
27
|
-
gemspec.description = "The Bullet plugin is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries) or when you're using eager loading that isn't necessary."
|
|
28
|
-
gemspec.email = "flyerhzm@gmail.com"
|
|
29
|
-
gemspec.homepage = "http://github.com/flyerhzm/bullet"
|
|
30
|
-
gemspec.authors = ["Richard Huang"]
|
|
31
|
-
gemspec.files.exclude '.gitignore'
|
|
32
|
-
gemspec.files.exclude 'log/*'
|
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
30
|
+
spec.pattern = "spec/**/*_spec.rb"
|
|
33
31
|
end
|
|
34
|
-
|
|
32
|
+
|
|
33
|
+
RSpec::Core::RakeTask.new('spec:progress') do |spec|
|
|
34
|
+
spec.rspec_opts = %w(--format progress)
|
|
35
|
+
spec.pattern = "spec/**/*_spec.rb"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
|
39
|
+
rdoc.rdoc_dir = "rdoc"
|
|
40
|
+
rdoc.title = "bullet #{Bullet::VERSION}"
|
|
41
|
+
rdoc.rdoc_files.include("README*")
|
|
42
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
task :default => :spec
|
data/bullet.gemspec
CHANGED
|
@@ -1,67 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
|
3
|
+
|
|
4
|
+
require "bullet/version"
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
|
-
s.name
|
|
8
|
-
s.version
|
|
7
|
+
s.name = "bullet"
|
|
8
|
+
s.version = Bullet::VERSION
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.authors = ["Richard Huang"]
|
|
11
|
+
s.email = ["flyerhzm@gmail.com"]
|
|
12
|
+
s.homepage = "http://github.com/flyerhzm/bullet"
|
|
13
|
+
s.summary = "A rails plugin to kill N+1 queries and unused eager loading."
|
|
14
|
+
s.description = "A rails plugin to kill N+1 queries and unused eager loading."
|
|
9
15
|
|
|
10
|
-
s.required_rubygems_version =
|
|
11
|
-
s.authors = ["Richard Huang"]
|
|
12
|
-
s.date = %q{2010-03-07}
|
|
13
|
-
s.description = %q{The Bullet plugin is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries) or when you're using eager loading that isn't necessary.}
|
|
14
|
-
s.email = %q{flyerhzm@gmail.com}
|
|
15
|
-
s.extra_rdoc_files = [
|
|
16
|
-
"README.textile",
|
|
17
|
-
"README_for_rails2.textile"
|
|
18
|
-
]
|
|
19
|
-
s.files = [
|
|
20
|
-
"MIT-LICENSE",
|
|
21
|
-
"README.textile",
|
|
22
|
-
"README_for_rails2.textile",
|
|
23
|
-
"Rakefile",
|
|
24
|
-
"VERSION",
|
|
25
|
-
"bullet.gemspec",
|
|
26
|
-
"lib/bullet.rb",
|
|
27
|
-
"lib/bullet/action_controller2.rb",
|
|
28
|
-
"lib/bullet/active_record2.rb",
|
|
29
|
-
"lib/bullet/active_record3.rb",
|
|
30
|
-
"lib/bullet/association.rb",
|
|
31
|
-
"lib/bullet/counter.rb",
|
|
32
|
-
"lib/bullet/logger.rb",
|
|
33
|
-
"lib/bullet/notification.rb",
|
|
34
|
-
"lib/bulletware.rb",
|
|
35
|
-
"rails/init.rb",
|
|
36
|
-
"spec/bullet/association_for_chris_spec.rb",
|
|
37
|
-
"spec/bullet/association_for_peschkaj_spec.rb",
|
|
38
|
-
"spec/bullet/association_spec.rb",
|
|
39
|
-
"spec/bullet/counter_spec.rb",
|
|
40
|
-
"spec/spec.opts",
|
|
41
|
-
"spec/spec_helper.rb",
|
|
42
|
-
"tasks/bullet_tasks.rake"
|
|
43
|
-
]
|
|
44
|
-
s.homepage = %q{http://github.com/flyerhzm/bullet}
|
|
45
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
|
46
|
-
s.require_paths = ["lib"]
|
|
47
|
-
s.rubygems_version = %q{1.3.6}
|
|
48
|
-
s.summary = %q{A plugin to kill N+1 queries and unused eager loading}
|
|
49
|
-
s.test_files = [
|
|
50
|
-
"spec/spec_helper.rb",
|
|
51
|
-
"spec/bullet/counter_spec.rb",
|
|
52
|
-
"spec/bullet/association_spec.rb",
|
|
53
|
-
"spec/bullet/association_for_chris_spec.rb",
|
|
54
|
-
"spec/bullet/association_for_peschkaj_spec.rb"
|
|
55
|
-
]
|
|
16
|
+
s.required_rubygems_version = ">= 1.3.6"
|
|
56
17
|
|
|
57
|
-
|
|
58
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
59
|
-
s.specification_version = 3
|
|
18
|
+
s.add_dependency "uniform_notifier", "~> 1.0.0"
|
|
60
19
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
else
|
|
65
|
-
end
|
|
20
|
+
s.files = `git ls-files`.split("\n")
|
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
22
|
+
s.require_paths = ["lib"]
|
|
66
23
|
end
|
|
67
24
|
|
|
@@ -4,6 +4,7 @@ module Bullet
|
|
|
4
4
|
require 'action_controller'
|
|
5
5
|
case Rails.version
|
|
6
6
|
when /^2.3/
|
|
7
|
+
::ActionController::Dispatcher.middleware.use Bullet::Rack
|
|
7
8
|
::ActionController::Dispatcher.class_eval do
|
|
8
9
|
class <<self
|
|
9
10
|
alias_method :origin_reload_application, :reload_application
|
|
@@ -21,21 +22,20 @@ module Bullet
|
|
|
21
22
|
Bullet.clear
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
::ActionController::Base.class_eval do
|
|
26
27
|
alias_method :origin_process, :process
|
|
27
28
|
def process(request, response, method = :perform_action, *arguments)
|
|
28
29
|
Bullet.start_request
|
|
29
30
|
response = origin_process(request, response, method = :perform_action, *arguments)
|
|
30
|
-
|
|
31
|
+
|
|
31
32
|
if Bullet.notification?
|
|
32
33
|
if response.headers["type"] and response.headers["type"].include? 'text/html' and response.body =~ %r{<html.*</html>}m
|
|
33
|
-
response.body <<= Bullet.
|
|
34
|
+
response.body <<= Bullet.gather_inline_notifications
|
|
34
35
|
response.headers["Content-Length"] = response.body.length.to_s
|
|
35
36
|
end
|
|
36
|
-
|
|
37
|
-
Bullet.
|
|
38
|
-
Bullet.log_notification(request.params['PATH_INFO'])
|
|
37
|
+
|
|
38
|
+
Bullet.perform_out_of_channel_notifications
|
|
39
39
|
end
|
|
40
40
|
Bullet.end_request
|
|
41
41
|
response
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module Bullet
|
|
2
|
+
LOAD_TARGET_RGX = /load_target/
|
|
2
3
|
module ActiveRecord
|
|
3
4
|
def self.enable
|
|
4
5
|
require 'active_record'
|
|
@@ -12,11 +13,11 @@ module Bullet
|
|
|
12
13
|
|
|
13
14
|
if records
|
|
14
15
|
if records.size > 1
|
|
15
|
-
Bullet::Association.add_possible_objects(records)
|
|
16
|
-
Bullet::Counter.add_possible_objects(records)
|
|
16
|
+
Bullet::Detector::Association.add_possible_objects(records)
|
|
17
|
+
Bullet::Detector::Counter.add_possible_objects(records)
|
|
17
18
|
elsif records.size == 1
|
|
18
|
-
Bullet::Association.add_impossible_object(records.first)
|
|
19
|
-
Bullet::Counter.add_impossible_object(records.first)
|
|
19
|
+
Bullet::Detector::Association.add_impossible_object(records.first)
|
|
20
|
+
Bullet::Detector::Counter.add_impossible_object(records.first)
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -33,9 +34,9 @@ module Bullet
|
|
|
33
34
|
records = [records].flatten.compact.uniq
|
|
34
35
|
return if records.empty?
|
|
35
36
|
records.each do |record|
|
|
36
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
37
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
37
38
|
end
|
|
38
|
-
Bullet::Association.add_eager_loadings(records, associations)
|
|
39
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
|
39
40
|
origin_preload_associations(records, associations, preload_options={})
|
|
40
41
|
end
|
|
41
42
|
end
|
|
@@ -47,10 +48,10 @@ module Bullet
|
|
|
47
48
|
records = origin_find_with_associations(options)
|
|
48
49
|
associations = merge_includes(scope(:find, :include), options[:include])
|
|
49
50
|
records.each do |record|
|
|
50
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
51
|
-
Bullet::
|
|
51
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
52
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
52
53
|
end
|
|
53
|
-
Bullet::Association.add_eager_loadings(records, associations)
|
|
54
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
|
54
55
|
records
|
|
55
56
|
end
|
|
56
57
|
end
|
|
@@ -60,8 +61,8 @@ module Bullet
|
|
|
60
61
|
alias_method :origin_construct_association, :construct_association
|
|
61
62
|
def construct_association(record, join, row)
|
|
62
63
|
associations = join.reflection.name
|
|
63
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
64
|
-
Bullet::
|
|
64
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
65
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
65
66
|
origin_construct_association(record, join, row)
|
|
66
67
|
end
|
|
67
68
|
end
|
|
@@ -70,7 +71,7 @@ module Bullet
|
|
|
70
71
|
# call one to many associations
|
|
71
72
|
alias_method :origin_load_target, :load_target
|
|
72
73
|
def load_target
|
|
73
|
-
Bullet::
|
|
74
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
74
75
|
origin_load_target
|
|
75
76
|
end
|
|
76
77
|
end
|
|
@@ -81,8 +82,8 @@ module Bullet
|
|
|
81
82
|
def load_target
|
|
82
83
|
# avoid stack level too deep
|
|
83
84
|
result = origin_load_target
|
|
84
|
-
Bullet::
|
|
85
|
-
Bullet::Association.add_possible_objects(result)
|
|
85
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless caller.find {|c| c =~ LOAD_TARGET_RGX }
|
|
86
|
+
Bullet::Detector::Association.add_possible_objects(result)
|
|
86
87
|
result
|
|
87
88
|
end
|
|
88
89
|
end
|
|
@@ -91,7 +92,7 @@ module Bullet
|
|
|
91
92
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
|
92
93
|
def has_cached_counter?
|
|
93
94
|
result = origin_has_cached_counter?
|
|
94
|
-
Bullet::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
95
|
+
Bullet::Detector::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
95
96
|
result
|
|
96
97
|
end
|
|
97
98
|
end
|
|
@@ -100,7 +101,7 @@ module Bullet
|
|
|
100
101
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
|
101
102
|
def has_cached_counter?
|
|
102
103
|
result = origin_has_cached_counter?
|
|
103
|
-
Bullet::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
104
|
+
Bullet::Detector::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
104
105
|
result
|
|
105
106
|
end
|
|
106
107
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module Bullet
|
|
2
|
+
LOAD_TARGET_RGX = /load_target/
|
|
2
3
|
module ActiveRecord
|
|
3
4
|
def self.enable
|
|
4
5
|
require 'active_record'
|
|
@@ -9,11 +10,11 @@ module Bullet
|
|
|
9
10
|
def to_a
|
|
10
11
|
records = origin_to_a
|
|
11
12
|
if records.size > 1
|
|
12
|
-
Bullet::Association.add_possible_objects(records)
|
|
13
|
-
Bullet::Counter.add_possible_objects(records)
|
|
13
|
+
Bullet::Detector::Association.add_possible_objects(records)
|
|
14
|
+
Bullet::Detector::Counter.add_possible_objects(records)
|
|
14
15
|
elsif records.size == 1
|
|
15
|
-
Bullet::Association.add_impossible_object(records.first)
|
|
16
|
-
Bullet::Counter.add_impossible_object(records.first)
|
|
16
|
+
Bullet::Detector::Association.add_impossible_object(records.first)
|
|
17
|
+
Bullet::Detector::Counter.add_impossible_object(records.first)
|
|
17
18
|
end
|
|
18
19
|
records
|
|
19
20
|
end
|
|
@@ -27,9 +28,9 @@ module Bullet
|
|
|
27
28
|
records = [records].flatten.compact.uniq
|
|
28
29
|
return if records.empty?
|
|
29
30
|
records.each do |record|
|
|
30
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
31
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
31
32
|
end
|
|
32
|
-
Bullet::Association.add_eager_loadings(records, associations)
|
|
33
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
|
33
34
|
origin_preload_associations(records, associations, preload_options={})
|
|
34
35
|
end
|
|
35
36
|
end
|
|
@@ -41,10 +42,10 @@ module Bullet
|
|
|
41
42
|
records = origin_find_with_associations
|
|
42
43
|
associations = (@eager_load_values + @includes_values).uniq
|
|
43
44
|
records.each do |record|
|
|
44
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
45
|
-
Bullet::
|
|
45
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
46
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
46
47
|
end
|
|
47
|
-
Bullet::Association.add_eager_loadings(records, associations)
|
|
48
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
|
48
49
|
records
|
|
49
50
|
end
|
|
50
51
|
end
|
|
@@ -54,8 +55,8 @@ module Bullet
|
|
|
54
55
|
# call join associations
|
|
55
56
|
def construct_association(record, join, row)
|
|
56
57
|
associations = join.reflection.name
|
|
57
|
-
Bullet::Association.add_object_associations(record, associations)
|
|
58
|
-
Bullet::
|
|
58
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
|
59
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
|
59
60
|
origin_construct_association(record, join, row)
|
|
60
61
|
end
|
|
61
62
|
end
|
|
@@ -64,7 +65,7 @@ module Bullet
|
|
|
64
65
|
# call one to many associations
|
|
65
66
|
alias_method :origin_load_target, :load_target
|
|
66
67
|
def load_target
|
|
67
|
-
Bullet::
|
|
68
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
|
68
69
|
origin_load_target
|
|
69
70
|
end
|
|
70
71
|
end
|
|
@@ -75,8 +76,8 @@ module Bullet
|
|
|
75
76
|
def load_target
|
|
76
77
|
# avoid stack level too deep
|
|
77
78
|
result = origin_load_target
|
|
78
|
-
Bullet::
|
|
79
|
-
Bullet::Association.add_possible_objects(result)
|
|
79
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless caller.find {|c| c =~ LOAD_TARGET_RGX }
|
|
80
|
+
Bullet::Detector::Association.add_possible_objects(result)
|
|
80
81
|
result
|
|
81
82
|
end
|
|
82
83
|
end
|
|
@@ -86,7 +87,7 @@ module Bullet
|
|
|
86
87
|
|
|
87
88
|
def has_cached_counter?
|
|
88
89
|
result = origin_has_cached_counter?
|
|
89
|
-
Bullet::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
90
|
+
Bullet::Detector::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
90
91
|
result
|
|
91
92
|
end
|
|
92
93
|
end
|
|
@@ -95,16 +96,7 @@ module Bullet
|
|
|
95
96
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
|
96
97
|
def has_cached_counter?
|
|
97
98
|
result = origin_has_cached_counter?
|
|
98
|
-
Bullet::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
99
|
-
result
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
::ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
|
|
104
|
-
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
|
105
|
-
def has_cached_counter?
|
|
106
|
-
result = origin_has_cached_counter?
|
|
107
|
-
Bullet::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
99
|
+
Bullet::Detector::Counter.add_counter_cache(@owner, @reflection.name) unless result
|
|
108
100
|
result
|
|
109
101
|
end
|
|
110
102
|
end
|