bullet 5.0.0 → 5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5439116cdedcd96dfad6dfd315eaf47ee815153
4
- data.tar.gz: 9542679b93fa670fbf8b014fb0cbd3adb13a30d8
3
+ metadata.gz: f726582290756f07599b35204f8e903fd20350b3
4
+ data.tar.gz: 2e4a9e95087d246cb69e887eef07868c2d9e0a63
5
5
  SHA512:
6
- metadata.gz: 4704ead627526344ab065d5d0a9bd2f3516165f664d9ab97aca3dd576c55ecc75450636daceebe21d100562be45c5e9352296ea0cd5856b0a4205be2120751cb
7
- data.tar.gz: 6b3d52be604e5188920592e6b3952d2a683364631739c097b619b151f9131b911454452eae824e13493a4866ff767eb9ba61da3a98097aa3042e498faf74bdd6
6
+ metadata.gz: 66c4b18f8c522a2cfa310bd8b818b177a12507c99255860881d225bac39722f35bfea65d7ea14287496f7fcf4d52d618e77ba712ebb28b2dad7a7a08909f56a8
7
+ data.tar.gz: f68a5397786c67ae3aefe57ce3030133f4c0f54a253add872dc54ba83ab00c33439325b6f0ee3500a0534bddca951e95b5929a8dfc0c74d8bf5c818b204992ad
@@ -1,6 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
+ - 1.9.3
4
5
  - 2.0
5
6
  - 2.1
6
7
  - 2.2
@@ -28,8 +29,38 @@ services:
28
29
  - mongodb
29
30
  matrix:
30
31
  exclude:
32
+ - rvm: 1.9.3
33
+ gemfile: Gemfile.rails-4.0
34
+ - rvm: 1.9.3
35
+ gemfile: Gemfile.rails-4.1
36
+ - rvm: 1.9.3
37
+ gemfile: Gemfile.rails-4.2
38
+ - rvm: 1.9.3
39
+ gemfile: Gemfile.rails-5.0
40
+ - rvm: 1.9.3
41
+ gemfile: Gemfile.mongoid-2.4
42
+ - rvm: 1.9.3
43
+ gemfile: Gemfile.mongoid-2.5
44
+ - rvm: 1.9.3
45
+ gemfile: Gemfile.mongoid-2.6
46
+ - rvm: 1.9.3
47
+ gemfile: Gemfile.mongoid-2.7
48
+ - rvm: 1.9.3
49
+ gemfile: Gemfile.mongoid-2.8
50
+ - rvm: 1.9.3
51
+ gemfile: Gemfile.mongoid-3.0
52
+ - rvm: 1.9.3
53
+ gemfile: Gemfile.mongoid-3.1
54
+ - rvm: 1.9.3
55
+ gemfile: Gemfile.mongoid-4.0
56
+ - rvm: 1.9.3
57
+ gemfile: Gemfile.mongoid-5.0
58
+ - rvm: 2.0
59
+ gemfile: Gemfile.rails-3.0
31
60
  - rvm: 2.0
32
61
  gemfile: Gemfile.rails-5.0
62
+ - rvm: 2.1
63
+ gemfile: Gemfile.rails-3.0
33
64
  - rvm: 2.1
34
65
  gemfile: Gemfile.rails-5.0
35
66
  - rvm: 2.2
@@ -1,55 +1,31 @@
1
1
  # Next Release
2
2
 
3
- ## 5.0.0 (01/06/2015)
3
+ ## 5.1.0 (05/21/2015)
4
4
 
5
- * Support Rails 5.0.0.beta1
5
+ * Fix false alert when `empty?` used with `counter_cache`
6
+ * Fix `alias_method_chain` deprecation for rails 5
7
+ * Add response handling for non-Rails Rack responses
8
+ * Fix false alert when querying immediately after creation
9
+ * Fix UnusedEagerLoading bug when multiple eager loading query include same objects
6
10
 
7
- ## 4.14.10
11
+ ## 5.0.0 (01/06/2015)
8
12
 
13
+ * Support Rails 5.0.0.beta1
9
14
  * Fix `has_many :through` infinite loop issue
10
-
11
- ## 4.14.9
12
-
13
15
  * Support mongoid 5.0.0
14
16
  * Do not report association queries immediately after object creation to
15
17
  require a preload
16
18
  * Detect `counter_cache` for `has_many :through` association
17
-
18
- ## 4.14.8
19
-
20
- * compatible with `composite_primary_keys` gem
21
-
22
- ## 4.14.7
23
-
19
+ * Compatible with `composite_primary_keys` gem
24
20
  * Fix AR 4.2 SingularAssociation#reader result can be nil
25
21
  * `perform_out_of_channel_notifications` should always be triggered
26
-
27
- ## 4.14.6
28
-
29
22
  * Fix false positive with `belongs_to` -> `belongs_to` for active\_record 4.2
30
23
  * Activate active\_record hacks only when Bullet already start
31
-
32
- ## 4.14.5
33
-
34
24
  * Don't execute query when running `to_sql`
35
25
  * Send backtrace to `uniform_notifier`
36
26
  * Fix sse response check
37
27
  * Dynamically delegate available notifiers to UniformNotifier
38
-
39
- ## 4.14.4
40
-
41
- * Fix false N + 1 warnings on Rails 4.2
42
-
43
- ## 4.14.3
44
-
45
- * Fix false positive on create
46
-
47
- ## 4.14.2
48
-
49
28
  * Hotfix nil object when `add_impossible_object`
50
-
51
- ## 4.14.1
52
-
53
29
  * Fix `has_one` then `has_many` associations in rails 4.2
54
30
  * Append js and dom to html body in proper position
55
31
 
@@ -5,7 +5,7 @@ gemspec
5
5
  gem 'rails', '~> 4.0.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 5.0.0.beta', github: 'mongoid'
8
+ gem 'mongoid', '~> 5.0.0'
9
9
 
10
10
  gem "rspec"
11
11
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 3.0.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 3.1.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 3.2.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 4.0.0'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 4.1.0'
6
6
  gem 'sqlite3'
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
@@ -6,6 +6,7 @@ gem 'rails', '~> 4.2.0'
6
6
  gem 'sqlite3'
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
8
  gem 'activerecord-import'
9
+ gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
9
10
 
10
11
  gem "rspec"
11
12
 
data/Hacking.md CHANGED
@@ -23,6 +23,7 @@ Notification instances contain the message that will be displayed, and will
23
23
  use a Presenter class to display their message to the user.
24
24
 
25
25
  So the flow of a request goes like this:
26
+
26
27
  1. Bullet.start_request is called, which resets all the detectors and empties
27
28
  the notification collector
28
29
  2. The request is handled by Rails, and the installed ActiveRecord extensions
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.required_rubygems_version = ">= 1.3.6"
19
19
 
20
20
  s.add_runtime_dependency "activesupport", ">= 3.0.0"
21
- s.add_runtime_dependency "uniform_notifier", "~> 1.9.0"
21
+ s.add_runtime_dependency "uniform_notifier", "~> 1.10.0"
22
22
 
23
23
  s.files = `git ls-files`.split("\n")
24
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -82,8 +82,8 @@ module Bullet
82
82
 
83
83
  def add_whitelist(options)
84
84
  reset_whitelist
85
- @whitelist[options[:type]][options[:class_name].classify] ||= []
86
- @whitelist[options[:type]][options[:class_name].classify] << options[:association].to_sym
85
+ @whitelist[options[:type]][options[:class_name]] ||= []
86
+ @whitelist[options[:type]][options[:class_name]] << options[:association].to_sym
87
87
  end
88
88
 
89
89
  def get_whitelist_associations(type, class_name)
@@ -23,6 +23,24 @@ module Bullet
23
23
  end
24
24
  end
25
25
 
26
+ ::ActiveRecord::Persistence.class_eval do
27
+ alias_method :origin_save, :save
28
+ def save(*args, &proc)
29
+ was_new_record = new_record?
30
+ origin_save(*args, &proc).tap do |result|
31
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
32
+ end
33
+ end
34
+
35
+ alias_method :origin_save!, :save!
36
+ def save!(*args, &proc)
37
+ was_new_record = new_record?
38
+ origin_save!(*args, &proc).tap do |result|
39
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
40
+ end
41
+ end
42
+ end
43
+
26
44
  ::ActiveRecord::AssociationPreload::ClassMethods.class_eval do
27
45
  alias_method :origin_preload_associations, :preload_associations
28
46
  # include query for one to many associations.
@@ -118,7 +136,7 @@ module Bullet
118
136
 
119
137
  alias_method :origin_empty?, :empty?
120
138
  def empty?
121
- if Bullet.start?
139
+ if Bullet.start? && !has_cached_counter?
122
140
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
123
141
  end
124
142
  origin_empty?
@@ -21,6 +21,24 @@ module Bullet
21
21
  end
22
22
  end
23
23
 
24
+ ::ActiveRecord::Persistence.class_eval do
25
+ alias_method :origin_save, :save
26
+ def save(*args, &proc)
27
+ was_new_record = new_record?
28
+ origin_save(*args, &proc).tap do |result|
29
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
30
+ end
31
+ end
32
+
33
+ alias_method :origin_save!, :save!
34
+ def save!(*args, &proc)
35
+ was_new_record = new_record?
36
+ origin_save!(*args, &proc).tap do |result|
37
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
38
+ end
39
+ end
40
+ end
41
+
24
42
  ::ActiveRecord::Associations::Preloader.class_eval do
25
43
  # include query for one to many associations.
26
44
  # keep this eager loadings.
@@ -100,7 +118,7 @@ module Bullet
100
118
 
101
119
  alias_method :origin_empty?, :empty?
102
120
  def empty?
103
- if Bullet.start?
121
+ if Bullet.start? && !has_cached_counter?(@reflection)
104
122
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
105
123
  end
106
124
  origin_empty?
@@ -29,6 +29,14 @@ module Bullet
29
29
  end
30
30
  end
31
31
  alias_method_chain :save, :bullet
32
+
33
+ def save_with_bullet!(*args, &proc)
34
+ was_new_record = new_record?
35
+ save_without_bullet!(*args, &proc).tap do |result|
36
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
37
+ end
38
+ end
39
+ alias_method_chain :save!, :bullet
32
40
  end
33
41
 
34
42
  ::ActiveRecord::Associations::Preloader.class_eval do
@@ -110,7 +118,7 @@ module Bullet
110
118
 
111
119
  alias_method :origin_empty?, :empty?
112
120
  def empty?
113
- if Bullet.start?
121
+ if Bullet.start? && !has_cached_counter?(@reflection)
114
122
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
115
123
  end
116
124
  origin_empty?
@@ -31,6 +31,14 @@ module Bullet
31
31
  end
32
32
  end
33
33
  alias_method_chain :save, :bullet
34
+
35
+ def save_with_bullet!(*args, &proc)
36
+ was_new_record = new_record?
37
+ save_without_bullet!(*args, &proc).tap do |result|
38
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
39
+ end
40
+ end
41
+ alias_method_chain :save!, :bullet
34
42
  end
35
43
 
36
44
  ::ActiveRecord::Associations::Preloader.class_eval do
@@ -113,7 +121,7 @@ module Bullet
113
121
 
114
122
  alias_method :origin_empty?, :empty?
115
123
  def empty?
116
- if Bullet.start?
124
+ if Bullet.start? && !has_cached_counter?(@reflection)
117
125
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
118
126
  end
119
127
  origin_empty?
@@ -29,6 +29,14 @@ module Bullet
29
29
  end
30
30
  end
31
31
  alias_method_chain :save, :bullet
32
+
33
+ def save_with_bullet!(*args, &proc)
34
+ was_new_record = new_record?
35
+ save_without_bullet!(*args, &proc).tap do |result|
36
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
37
+ end
38
+ end
39
+ alias_method_chain :save!, :bullet
32
40
  end
33
41
 
34
42
  ::ActiveRecord::Relation.class_eval do
@@ -143,7 +151,7 @@ module Bullet
143
151
 
144
152
  alias_method :origin_empty?, :empty?
145
153
  def empty?
146
- if Bullet.start?
154
+ if Bullet.start? && !has_cached_counter?(@reflection)
147
155
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
148
156
  end
149
157
  origin_empty?
@@ -183,7 +191,7 @@ module Bullet
183
191
  Thread.current[:bullet_collection_empty] = true
184
192
  result = origin_many_empty?
185
193
  Thread.current[:bullet_collection_empty] = nil
186
- if Bullet.start?
194
+ if Bullet.start? && !has_cached_counter?(@reflection)
187
195
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
188
196
  end
189
197
  result
@@ -1,4 +1,20 @@
1
1
  module Bullet
2
+ module SaveWithBulletSupport
3
+ def save(*args)
4
+ was_new_record = new_record?
5
+ super(*args).tap do |result|
6
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
7
+ end
8
+ end
9
+
10
+ def save!(*args)
11
+ was_new_record = new_record?
12
+ super(*args).tap do |result|
13
+ Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
14
+ end
15
+ end
16
+ end
17
+
2
18
  module ActiveRecord
3
19
  def self.enable
4
20
  require 'active_record'
@@ -21,15 +37,7 @@ module Bullet
21
37
  end
22
38
  end
23
39
 
24
- ::ActiveRecord::Persistence.class_eval do
25
- def save_with_bullet(*args, &proc)
26
- was_new_record = new_record?
27
- save_without_bullet(*args, &proc).tap do |result|
28
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
29
- end
30
- end
31
- alias_method_chain :save, :bullet
32
- end
40
+ ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
33
41
 
34
42
  ::ActiveRecord::Relation.class_eval do
35
43
  alias_method :origin_to_a, :to_a
@@ -151,7 +159,7 @@ module Bullet
151
159
 
152
160
  alias_method :origin_empty?, :empty?
153
161
  def empty?
154
- if Bullet.start?
162
+ if Bullet.start? && !@reflection.has_cached_counter?
155
163
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
156
164
  end
157
165
  origin_empty?
@@ -191,7 +199,7 @@ module Bullet
191
199
  Thread.current[:bullet_collection_empty] = true
192
200
  result = origin_many_empty?
193
201
  Thread.current[:bullet_collection_empty] = nil
194
- if Bullet.start?
202
+ if Bullet.start? && !@reflection.has_cached_counter?
195
203
  Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
196
204
  end
197
205
  result
@@ -27,27 +27,25 @@ module Bullet
27
27
  Bullet.debug("Detector::UnusedEagerLoading#add_eager_loadings", "objects: #{objects.map(&:bullet_key).join(', ')}, associations: #{associations}")
28
28
  bullet_keys = objects.map(&:bullet_key)
29
29
 
30
- to_add = nil
31
- to_merge, to_delete = [], []
30
+ to_add, to_merge, to_delete = [], [], []
32
31
  eager_loadings.each do |k, v|
33
32
  key_objects_overlap = k & bullet_keys
34
33
 
35
34
  next if key_objects_overlap.empty?
36
35
 
36
+ bullet_keys = bullet_keys - k
37
37
  if key_objects_overlap == k
38
- to_add = [k, associations]
39
- break
38
+ to_add << [k, associations]
40
39
  else
41
40
  to_merge << [key_objects_overlap, ( eager_loadings[k].dup << associations )]
42
41
 
43
- keys_without_objects = k - bullet_keys
42
+ keys_without_objects = k - key_objects_overlap
44
43
  to_merge << [keys_without_objects, eager_loadings[k]]
45
44
  to_delete << k
46
- bullet_keys = bullet_keys - k
47
45
  end
48
46
  end
49
47
 
50
- eager_loadings.add(*to_add) if to_add
48
+ to_add.each { |k, val| eager_loadings.add k, val }
51
49
  to_merge.each { |k, val| eager_loadings.merge k, val }
52
50
  to_delete.each { |k| eager_loadings.delete k }
53
51
 
@@ -57,11 +57,11 @@ module Bullet
57
57
  end
58
58
 
59
59
  def eql?(other)
60
- klazz_associations_str == other.klazz_associations_str
60
+ self.class == other.class && klazz_associations_str == other.klazz_associations_str
61
61
  end
62
62
 
63
63
  def hash
64
- klazz_associations_str.hash
64
+ [self.class, klazz_associations_str].hash
65
65
  end
66
66
 
67
67
  protected
@@ -67,7 +67,7 @@ module Bullet
67
67
  end
68
68
 
69
69
  def response_body(response)
70
- if rails?
70
+ if response.respond_to?(:body)
71
71
  Array === response.body ? response.body.first : response.body
72
72
  else
73
73
  response.first
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Bullet
3
- VERSION = "5.0.0"
3
+ VERSION = "5.1.0"
4
4
  end
@@ -5,7 +5,8 @@ module Bullet
5
5
  describe UnusedEagerLoading do
6
6
  before(:all) do
7
7
  @post = Post.first
8
- @post2 = Post.last
8
+ @post2 = Post.all[1]
9
+ @post3 = Post.last
9
10
  end
10
11
 
11
12
  context ".call_associations" do
@@ -72,7 +73,18 @@ module Bullet
72
73
  UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
73
74
  expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
74
75
  expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
75
- expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association2)
76
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.bullet_key], :association2)
77
+ end
78
+
79
+ it "should vmerge objects recursively, associations pair for existing eager_loadings" do
80
+ UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
81
+ UnusedEagerLoading.add_eager_loadings([@post, @post3], :association1)
82
+ UnusedEagerLoading.add_eager_loadings([@post, @post3], :association2)
83
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
84
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
85
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.bullet_key], :association1)
86
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post3.bullet_key], :association1)
87
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post3.bullet_key], :association2)
76
88
  end
77
89
 
78
90
  it "should delete objects, associations pair for existing eager_loadings" do
@@ -93,5 +93,36 @@ module Bullet
93
93
  end
94
94
  end
95
95
  end
96
+
97
+ describe "#response_body" do
98
+ let(:response) { double }
99
+ let(:body_string) { "<html><body>My Body</body></html>" }
100
+
101
+ context "when `response` responds to `body`" do
102
+ before { allow(response).to receive(:body).and_return(body) }
103
+
104
+ context "when `body` returns an Array" do
105
+ let(:body) { [body_string, 'random string'] }
106
+ it "should return the plain body string" do
107
+ expect(middleware.response_body(response)).to eq body_string
108
+ end
109
+ end
110
+
111
+ context "when `body` does not return an Array" do
112
+ let(:body) { body_string }
113
+ it "should return the plain body string" do
114
+ expect(middleware.response_body(response)).to eq body_string
115
+ end
116
+ end
117
+ end
118
+
119
+ context "when `response` does not respond to `body`" do
120
+ before { allow(response).to receive(:first).and_return(body_string) }
121
+
122
+ it "should return the plain body string" do
123
+ expect(middleware.response_body(response)).to eq body_string
124
+ end
125
+ end
126
+ end
96
127
  end
97
128
  end
@@ -85,4 +85,13 @@ describe Bullet, focused: true do
85
85
  end
86
86
  end
87
87
  end
88
+
89
+ describe '#add_whitelist' do
90
+ context "for 'special' class names" do
91
+ it 'is added to the whitelist successfully' do
92
+ Bullet.add_whitelist(:type => :n_plus_one_query, :class_name => 'Klass', :association => :department)
93
+ expect(Bullet.get_whitelist_associations(:n_plus_one_query, 'Klass')).to include :department
94
+ end
95
+ end
96
+ end
88
97
  end
@@ -72,6 +72,16 @@ if !mongoid? && active_record3?
72
72
 
73
73
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
74
74
  end
75
+
76
+ it "should not detect unused preload person => pets with empty?" do
77
+ Person.all.each do |person|
78
+ person.pets.empty?
79
+ end
80
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
81
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
82
+
83
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
84
+ end
75
85
  end
76
86
 
77
87
  context "category => posts => comments" do
@@ -537,6 +547,50 @@ if !mongoid? && active_record3?
537
547
  end
538
548
  end
539
549
 
550
+ describe Bullet::Detector::Association, "query immediately after creation" do
551
+ context "with save" do
552
+ context "document => children" do
553
+ it 'should not detect non preload associations' do
554
+ document1 = Document.new
555
+ document1.children.build
556
+ document1.save
557
+
558
+ document2 = Document.new(parent: document1)
559
+ document2.save
560
+ document2.parent
561
+
562
+ document1.children.each.first
563
+
564
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
565
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
566
+
567
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
568
+ end
569
+ end
570
+ end
571
+
572
+ context "with save!" do
573
+ context "document => children" do
574
+ it 'should not detect non preload associations' do
575
+ document1 = Document.new
576
+ document1.children.build
577
+ document1.save!
578
+
579
+ document2 = Document.new(parent: document1)
580
+ document2.save!
581
+ document2.parent
582
+
583
+ document1.children.each.first
584
+
585
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
586
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
587
+
588
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
589
+ end
590
+ end
591
+ end
592
+ end
593
+
540
594
  describe Bullet::Detector::Association, "STI" do
541
595
  context "page => author" do
542
596
  it "should detect non preload associations" do
@@ -72,6 +72,16 @@ if !mongoid? && active_record4?
72
72
 
73
73
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
74
74
  end
75
+
76
+ it "should not detect unused preload person => pets with empty?" do
77
+ Person.all.each do |person|
78
+ person.pets.empty?
79
+ end
80
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
81
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
82
+
83
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
84
+ end
75
85
  end
76
86
 
77
87
  context "category => posts => comments" do
@@ -561,22 +571,45 @@ if !mongoid? && active_record4?
561
571
  end
562
572
 
563
573
  describe Bullet::Detector::Association, "query immediately after creation" do
564
- context "document => children" do
565
- it 'should not detect non preload associations' do
566
- document1 = Document.new
567
- document1.children.build
568
- document1.save
574
+ context "with save" do
575
+ context "document => children" do
576
+ it 'should not detect non preload associations' do
577
+ document1 = Document.new
578
+ document1.children.build
579
+ document1.save
569
580
 
570
- document2 = Document.new(parent: document1)
571
- document2.save
572
- document2.parent
581
+ document2 = Document.new(parent: document1)
582
+ document2.save
583
+ document2.parent
573
584
 
574
- document1.children.each.first
585
+ document1.children.each.first
575
586
 
576
- Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
577
- expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
587
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
588
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
578
589
 
579
- expect(Bullet::Detector::Association).to be_completely_preloading_associations
590
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
591
+ end
592
+ end
593
+ end
594
+
595
+ context "with save!" do
596
+ context "document => children" do
597
+ it 'should not detect non preload associations' do
598
+ document1 = Document.new
599
+ document1.children.build
600
+ document1.save!
601
+
602
+ document2 = Document.new(parent: document1)
603
+ document2.save!
604
+ document2.parent
605
+
606
+ document1.children.each.first
607
+
608
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
609
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
610
+
611
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
612
+ end
580
613
  end
581
614
  end
582
615
  end
@@ -72,6 +72,16 @@ if !mongoid? && active_record5?
72
72
 
73
73
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
74
74
  end
75
+
76
+ it "should not detect unused preload person => pets with empty?" do
77
+ Person.all.each do |person|
78
+ person.pets.empty?
79
+ end
80
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
81
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
82
+
83
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
84
+ end
75
85
  end
76
86
 
77
87
  context "category => posts => comments" do
@@ -561,22 +571,45 @@ if !mongoid? && active_record5?
561
571
  end
562
572
 
563
573
  describe Bullet::Detector::Association, "query immediately after creation" do
564
- context "document => children" do
565
- it 'should not detect non preload associations' do
566
- document1 = Document.new
567
- document1.children.build
568
- document1.save
574
+ context "with save" do
575
+ context "document => children" do
576
+ it 'should not detect non preload associations' do
577
+ document1 = Document.new
578
+ document1.children.build
579
+ document1.save
569
580
 
570
- document2 = Document.new(parent: document1)
571
- document2.save
572
- document2.parent
581
+ document2 = Document.new(parent: document1)
582
+ document2.save
583
+ document2.parent
573
584
 
574
- document1.children.each.first
585
+ document1.children.each.first
575
586
 
576
- Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
577
- expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
587
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
588
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
578
589
 
579
- expect(Bullet::Detector::Association).to be_completely_preloading_associations
590
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
591
+ end
592
+ end
593
+ end
594
+
595
+ context "with save!" do
596
+ context "document => children" do
597
+ it 'should not detect non preload associations' do
598
+ document1 = Document.new
599
+ document1.children.build
600
+ document1.save!
601
+
602
+ document2 = Document.new(parent: document1)
603
+ document2.save!
604
+ document2.parent
605
+
606
+ document1.children.each.first
607
+
608
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
609
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
610
+
611
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
612
+ end
580
613
  end
581
614
  end
582
615
  end
data/test.sh CHANGED
@@ -1,5 +1,6 @@
1
1
  #bundle update rails && bundle exec rspec spec
2
2
  #BUNDLE_GEMFILE=Gemfile.mongoid bundle update mongoid && BUNDLE_GEMFILE=Gemfile.mongoid bundle exec rspec spec
3
+ BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle exec rspec spec
3
4
  BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle exec rspec spec
4
5
  BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle exec rspec spec
5
6
  BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle exec rspec spec
data/update.sh CHANGED
@@ -1,3 +1,4 @@
1
+ BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle update
1
2
  BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle update
2
3
  BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle update
3
4
  BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle update
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.0.0
4
+ version: 5.1.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: 2016-01-05 00:00:00.000000000 Z
11
+ date: 2016-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.9.0
33
+ version: 1.10.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.9.0
40
+ version: 1.10.0
41
41
  description: help to kill N+1 queries and unused eager loading.
42
42
  email:
43
43
  - flyerhzm@gmail.com