bullet 4.3.1 → 4.4.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 +4 -4
- data/lib/bullet/active_record3x.rb +3 -3
- data/lib/bullet/active_record4.rb +94 -0
- data/lib/bullet/dependency.rb +3 -1
- data/lib/bullet/version.rb +1 -1
- data/spec/integration/association_spec.rb +14 -14
- data/spec/integration/counter_spec.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ecb17e9a4a015f9ff8895fc39a7ed2bd3a5e600
|
4
|
+
data.tar.gz: a624e5f8bc8d40f8bf49eab595725ce2de0076c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e05204d7d248ac6888897a4235b716c4c74dbf793083f1aec5a693d88d1250ab6c12854967e93096c667e7a73b9bf54cc10799fd8428c7a67d7bc1672db288a4
|
7
|
+
data.tar.gz: 4bfdcde512f2583b6285663722c526972d7263aaeffc62173f651feaca77384c9a98678518286789fe79b3923393e7bf8e76bb33b7438df4c4033ff0c08206a8
|
data/.travis.yml
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
3
|
+
- 2.0.0
|
4
4
|
gemfile:
|
5
5
|
- Gemfile
|
6
6
|
- Gemfile.rails-4-beta
|
7
|
-
- Gemfile.rails-3.
|
8
|
-
- Gemfile.rails-3.
|
9
|
-
- Gemfile.rails-
|
7
|
+
- Gemfile.rails-3.2.12
|
8
|
+
- Gemfile.rails-3.1.11
|
9
|
+
- Gemfile.rails-3.0.20
|
10
10
|
env: DB=sqlite
|
11
11
|
services: mongodb
|
12
12
|
before_install:
|
@@ -23,8 +23,8 @@ module Bullet
|
|
23
23
|
# include query for one to many associations.
|
24
24
|
# keep this eager loadings.
|
25
25
|
alias_method :origin_initialize, :initialize
|
26
|
-
def initialize(records, associations,
|
27
|
-
origin_initialize(records, associations,
|
26
|
+
def initialize(records, associations, preload_scope = nil)
|
27
|
+
origin_initialize(records, associations, preload_scope)
|
28
28
|
records = [records].flatten.compact.uniq
|
29
29
|
return if records.empty?
|
30
30
|
records.each do |record|
|
@@ -39,7 +39,7 @@ module Bullet
|
|
39
39
|
alias_method :origin_find_with_associations, :find_with_associations
|
40
40
|
def find_with_associations
|
41
41
|
records = origin_find_with_associations
|
42
|
-
associations = (
|
42
|
+
associations = (eager_load_values + includes_values).uniq
|
43
43
|
records.each do |record|
|
44
44
|
Bullet::Detector::Association.add_object_associations(record, associations)
|
45
45
|
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Bullet
|
2
|
+
module ActiveRecord
|
3
|
+
def self.enable
|
4
|
+
require 'active_record'
|
5
|
+
::ActiveRecord::Relation.class_eval do
|
6
|
+
alias_method :origin_to_a, :to_a
|
7
|
+
# if select a collection of objects, then these objects have possible to cause N+1 query.
|
8
|
+
# if select only one object, then the only one object has impossible to cause N+1 query.
|
9
|
+
def to_a
|
10
|
+
records = origin_to_a
|
11
|
+
if records.size > 1
|
12
|
+
Bullet::Detector::Association.add_possible_objects(records)
|
13
|
+
Bullet::Detector::Counter.add_possible_objects(records)
|
14
|
+
elsif records.size == 1
|
15
|
+
Bullet::Detector::Association.add_impossible_object(records.first)
|
16
|
+
Bullet::Detector::Counter.add_impossible_object(records.first)
|
17
|
+
end
|
18
|
+
records
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
::ActiveRecord::Associations::Preloader.class_eval do
|
23
|
+
# include query for one to many associations.
|
24
|
+
# keep this eager loadings.
|
25
|
+
alias_method :origin_initialize, :initialize
|
26
|
+
def initialize(records, associations, preload_scope = nil)
|
27
|
+
origin_initialize(records, associations, preload_scope)
|
28
|
+
records = [records].flatten.compact.uniq
|
29
|
+
return if records.empty?
|
30
|
+
records.each do |record|
|
31
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
32
|
+
end
|
33
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
::ActiveRecord::FinderMethods.class_eval do
|
38
|
+
# add includes in scope
|
39
|
+
alias_method :origin_find_with_associations, :find_with_associations
|
40
|
+
def find_with_associations
|
41
|
+
records = origin_find_with_associations
|
42
|
+
associations = (eager_load_values + includes_values).uniq
|
43
|
+
records.each do |record|
|
44
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
45
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
46
|
+
end
|
47
|
+
Bullet::Detector::Association.add_eager_loadings(records, associations)
|
48
|
+
records
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
::ActiveRecord::Associations::JoinDependency.class_eval do
|
53
|
+
alias_method :origin_construct_association, :construct_association
|
54
|
+
# call join associations
|
55
|
+
def construct_association(record, join, row)
|
56
|
+
associations = join.reflection.name
|
57
|
+
Bullet::Detector::Association.add_object_associations(record, associations)
|
58
|
+
Bullet::Detector::NPlusOneQuery.call_association(record, associations)
|
59
|
+
origin_construct_association(record, join, row)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
::ActiveRecord::Associations::CollectionAssociation.class_eval do
|
64
|
+
# call one to many associations
|
65
|
+
alias_method :origin_load_target, :load_target
|
66
|
+
def load_target
|
67
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
68
|
+
origin_load_target
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
::ActiveRecord::Associations::SingularAssociation.class_eval do
|
73
|
+
# call has_one and belongs_to associations
|
74
|
+
alias_method :origin_reader, :reader
|
75
|
+
def reader(force_reload = false)
|
76
|
+
result = origin_reader(force_reload)
|
77
|
+
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
78
|
+
Bullet::Detector::Association.add_possible_objects(result)
|
79
|
+
result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
84
|
+
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
85
|
+
|
86
|
+
def has_cached_counter?(reflection = reflection)
|
87
|
+
result = origin_has_cached_counter?(reflection)
|
88
|
+
Bullet::Detector::Counter.add_counter_cache(owner, reflection.name) unless result
|
89
|
+
result
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/bullet/dependency.rb
CHANGED
@@ -24,8 +24,10 @@ module Bullet
|
|
24
24
|
'active_record2'
|
25
25
|
elsif active_record30?
|
26
26
|
'active_record3'
|
27
|
-
elsif active_record31? || active_record32?
|
27
|
+
elsif active_record31? || active_record32?
|
28
28
|
'active_record3x'
|
29
|
+
elsif active_record4?
|
30
|
+
'active_record4'
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
data/lib/bullet/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
if active_record3?
|
3
|
+
if active_record3? || active_record4?
|
4
4
|
describe Bullet::Detector::Association, 'has_many' do
|
5
5
|
before(:each) do
|
6
6
|
Bullet.clear
|
@@ -66,7 +66,7 @@ if active_record3?
|
|
66
66
|
it "should detect preload category => posts, but no post => comments" do
|
67
67
|
Category.includes(:posts).each do |category|
|
68
68
|
category.posts.each do |post|
|
69
|
-
post.comments.
|
69
|
+
post.comments.map(&:name)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
@@ -176,7 +176,7 @@ if active_record3?
|
|
176
176
|
end
|
177
177
|
|
178
178
|
it "should detect preload with post => commnets" do
|
179
|
-
Post.first.comments.
|
179
|
+
Post.first.comments.map(&:name)
|
180
180
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
181
181
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
182
182
|
|
@@ -199,7 +199,7 @@ if active_record3?
|
|
199
199
|
|
200
200
|
context "scope for_category_name" do
|
201
201
|
it "should detect preload with post => category" do
|
202
|
-
Post.in_category_name('first').
|
202
|
+
Post.in_category_name('first').each do |post|
|
203
203
|
post.category.name
|
204
204
|
end
|
205
205
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
@@ -278,7 +278,7 @@ if active_record3?
|
|
278
278
|
end
|
279
279
|
|
280
280
|
it "should not detect preload with comment => post" do
|
281
|
-
Comment.all.
|
281
|
+
Comment.all.map(&:name)
|
282
282
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
283
283
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
284
284
|
|
@@ -415,7 +415,7 @@ if active_record3?
|
|
415
415
|
end
|
416
416
|
|
417
417
|
it "should detect no unused preload associations" do
|
418
|
-
Student.all.
|
418
|
+
Student.all.map(&:name)
|
419
419
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
420
420
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
421
421
|
|
@@ -456,7 +456,7 @@ if active_record3?
|
|
456
456
|
end
|
457
457
|
|
458
458
|
it "should not detect preload associations" do
|
459
|
-
Firm.all.
|
459
|
+
Firm.all.map(&:name)
|
460
460
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
461
461
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
462
462
|
|
@@ -464,7 +464,7 @@ if active_record3?
|
|
464
464
|
end
|
465
465
|
|
466
466
|
it "should detect unused preload associations" do
|
467
|
-
Firm.includes(:clients).
|
467
|
+
Firm.includes(:clients).map(&:name)
|
468
468
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
469
469
|
Bullet::Detector::Association.should be_unused_preload_associations_for(Firm, :clients)
|
470
470
|
|
@@ -495,7 +495,7 @@ if active_record3?
|
|
495
495
|
end
|
496
496
|
|
497
497
|
it "should detect preload association" do
|
498
|
-
Company.
|
498
|
+
Company.includes(:address).each do |company|
|
499
499
|
company.address.name
|
500
500
|
end
|
501
501
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
@@ -505,7 +505,7 @@ if active_record3?
|
|
505
505
|
end
|
506
506
|
|
507
507
|
it "should not detect preload association" do
|
508
|
-
Company.all.
|
508
|
+
Company.all.map(&:name)
|
509
509
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
510
510
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
511
511
|
|
@@ -513,7 +513,7 @@ if active_record3?
|
|
513
513
|
end
|
514
514
|
|
515
515
|
it "should detect unused preload association" do
|
516
|
-
Company.
|
516
|
+
Company.includes(:address).map(&:name)
|
517
517
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
518
518
|
Bullet::Detector::Association.should be_unused_preload_associations_for(Company, :address)
|
519
519
|
|
@@ -564,7 +564,7 @@ if active_record3?
|
|
564
564
|
end
|
565
565
|
|
566
566
|
it "should detect preload associations" do
|
567
|
-
Page.
|
567
|
+
Page.includes(:author).each do |page|
|
568
568
|
page.author.name
|
569
569
|
end
|
570
570
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
@@ -574,7 +574,7 @@ if active_record3?
|
|
574
574
|
end
|
575
575
|
|
576
576
|
it "should detect unused preload associations" do
|
577
|
-
Page.
|
577
|
+
Page.includes(:author).map(&:name)
|
578
578
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
579
579
|
Bullet::Detector::Association.should be_unused_preload_associations_for(Page, :author)
|
580
580
|
|
@@ -582,7 +582,7 @@ if active_record3?
|
|
582
582
|
end
|
583
583
|
|
584
584
|
it "should not detect preload associations" do
|
585
|
-
Page.all.
|
585
|
+
Page.all.map(&:name)
|
586
586
|
Bullet::Detector::UnusedEagerAssociation.check_unused_preload_associations
|
587
587
|
Bullet::Detector::Association.should_not be_has_unused_preload_associations
|
588
588
|
|
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: 4.
|
4
|
+
version: 4.4.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: 2013-03-
|
11
|
+
date: 2013-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uniform_notifier
|
@@ -54,6 +54,7 @@ files:
|
|
54
54
|
- lib/bullet/active_record2.rb
|
55
55
|
- lib/bullet/active_record3.rb
|
56
56
|
- lib/bullet/active_record3x.rb
|
57
|
+
- lib/bullet/active_record4.rb
|
57
58
|
- lib/bullet/dependency.rb
|
58
59
|
- lib/bullet/detector.rb
|
59
60
|
- lib/bullet/detector/association.rb
|
@@ -157,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
158
|
version: 1.3.6
|
158
159
|
requirements: []
|
159
160
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.0.
|
161
|
+
rubygems_version: 2.0.2
|
161
162
|
signing_key:
|
162
163
|
specification_version: 4
|
163
164
|
summary: A rails plugin to kill N+1 queries and unused eager loading.
|