bullet 5.4.3 → 5.5.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.
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Bullet
3
- VERSION = "5.4.3"
3
+ VERSION = "5.5.0"
4
4
  end
@@ -5,10 +5,10 @@ module Bullet
5
5
  describe NPlusOneQuery do
6
6
  subject { NPlusOneQuery.new([["caller1", "caller2"]], Post, [:comments, :votes], "path") }
7
7
 
8
- it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n") }
9
- it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([ " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2\n" ]) }
8
+ it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n") }
9
+ it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([ " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n" ]) }
10
10
  it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]") }
11
- it { expect(subject.title).to eq("N+1 Query in path") }
11
+ it { expect(subject.title).to eq("USE eager loading in path") }
12
12
  end
13
13
  end
14
14
  end
@@ -6,7 +6,7 @@ module Bullet
6
6
  subject { UnusedEagerLoading.new([""], Post, [:comments, :votes], "path") }
7
7
 
8
8
  it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Remove from your finder: :includes => [:comments, :votes]") }
9
- it { expect(subject.title).to eq("Unused Eager Loading in path") }
9
+ it { expect(subject.title).to eq("AVOID eager loading in path") }
10
10
  end
11
11
  end
12
12
  end
@@ -29,6 +29,13 @@ if !mongoid? && active_record?
29
29
  expect(Bullet.collected_counter_cache_notifications).to be_empty
30
30
  end
31
31
 
32
+ it "should not need counter cache without size" do
33
+ Country.includes(:cities).each do |country|
34
+ country.cities.empty?
35
+ end
36
+ expect(Bullet.collected_counter_cache_notifications).to be_empty
37
+ end
38
+
32
39
  if active_record5?
33
40
  it "should not need counter cache for has_many through" do
34
41
  Client.all.each do |client|
data/test.sh CHANGED
@@ -4,15 +4,6 @@ BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.0 bund
4
4
  BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle exec rspec spec
5
5
  BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle exec rspec spec
6
6
  BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle exec rspec spec
7
- BUNDLE_GEMFILE=Gemfile.rails-3.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-3.2 bundle exec rspec spec
8
- BUNDLE_GEMFILE=Gemfile.rails-3.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-3.1 bundle exec rspec spec
9
- BUNDLE_GEMFILE=Gemfile.rails-3.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-3.0 bundle exec rspec spec
7
+ BUNDLE_GEMFILE=Gemfile.mongoid-6.0 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-6.0 bundle exec rspec spec
10
8
  BUNDLE_GEMFILE=Gemfile.mongoid-5.0 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-5.0 bundle exec rspec spec
11
9
  BUNDLE_GEMFILE=Gemfile.mongoid-4.0 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-4.0 bundle exec rspec spec
12
- BUNDLE_GEMFILE=Gemfile.mongoid-3.1 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-3.1 bundle exec rspec spec
13
- BUNDLE_GEMFILE=Gemfile.mongoid-3.0 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-3.0 bundle exec rspec spec
14
- BUNDLE_GEMFILE=Gemfile.mongoid-2.8 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-2.8 bundle exec rspec spec
15
- BUNDLE_GEMFILE=Gemfile.mongoid-2.7 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-2.7 bundle exec rspec spec
16
- BUNDLE_GEMFILE=Gemfile.mongoid-2.6 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-2.6 bundle exec rspec spec
17
- BUNDLE_GEMFILE=Gemfile.mongoid-2.5 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-2.5 bundle exec rspec spec
18
- BUNDLE_GEMFILE=Gemfile.mongoid-2.4 bundle && BUNDLE_GEMFILE=Gemfile.mongoid-2.4 bundle exec rspec spec
data/update.sh CHANGED
@@ -2,15 +2,6 @@ BUNDLE_GEMFILE=Gemfile.rails-5.0 bundle update
2
2
  BUNDLE_GEMFILE=Gemfile.rails-4.2 bundle update
3
3
  BUNDLE_GEMFILE=Gemfile.rails-4.1 bundle update
4
4
  BUNDLE_GEMFILE=Gemfile.rails-4.0 bundle update
5
- BUNDLE_GEMFILE=Gemfile.rails-3.2 bundle update
6
- BUNDLE_GEMFILE=Gemfile.rails-3.1 bundle update
7
- BUNDLE_GEMFILE=Gemfile.rails-3.0 bundle update
5
+ BUNDLE_GEMFILE=Gemfile.mongoid-6.0 bundle update
8
6
  BUNDLE_GEMFILE=Gemfile.mongoid-5.0 bundle update
9
7
  BUNDLE_GEMFILE=Gemfile.mongoid-4.0 bundle update
10
- BUNDLE_GEMFILE=Gemfile.mongoid-3.1 bundle update
11
- BUNDLE_GEMFILE=Gemfile.mongoid-3.0 bundle update
12
- BUNDLE_GEMFILE=Gemfile.mongoid-2.8 bundle update
13
- BUNDLE_GEMFILE=Gemfile.mongoid-2.7 bundle update
14
- BUNDLE_GEMFILE=Gemfile.mongoid-2.6 bundle update
15
- BUNDLE_GEMFILE=Gemfile.mongoid-2.5 bundle update
16
- BUNDLE_GEMFILE=Gemfile.mongoid-2.4 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.4.3
4
+ version: 5.5.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-12-13 00:00:00.000000000 Z
11
+ date: 2016-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -51,18 +51,9 @@ files:
51
51
  - CHANGELOG.md
52
52
  - Gemfile
53
53
  - Gemfile.mongoid
54
- - Gemfile.mongoid-2.4
55
- - Gemfile.mongoid-2.5
56
- - Gemfile.mongoid-2.6
57
- - Gemfile.mongoid-2.7
58
- - Gemfile.mongoid-2.8
59
- - Gemfile.mongoid-3.0
60
- - Gemfile.mongoid-3.1
61
54
  - Gemfile.mongoid-4.0
62
55
  - Gemfile.mongoid-5.0
63
- - Gemfile.rails-3.0
64
- - Gemfile.rails-3.1
65
- - Gemfile.rails-3.2
56
+ - Gemfile.mongoid-6.0
66
57
  - Gemfile.rails-4.0
67
58
  - Gemfile.rails-4.1
68
59
  - Gemfile.rails-4.2
@@ -74,8 +65,6 @@ files:
74
65
  - Rakefile
75
66
  - bullet.gemspec
76
67
  - lib/bullet.rb
77
- - lib/bullet/active_record3.rb
78
- - lib/bullet/active_record3x.rb
79
68
  - lib/bullet/active_record4.rb
80
69
  - lib/bullet/active_record41.rb
81
70
  - lib/bullet/active_record42.rb
@@ -89,10 +78,9 @@ files:
89
78
  - lib/bullet/detector/unused_eager_loading.rb
90
79
  - lib/bullet/ext/object.rb
91
80
  - lib/bullet/ext/string.rb
92
- - lib/bullet/mongoid2x.rb
93
- - lib/bullet/mongoid3x.rb
94
81
  - lib/bullet/mongoid4x.rb
95
82
  - lib/bullet/mongoid5x.rb
83
+ - lib/bullet/mongoid6x.rb
96
84
  - lib/bullet/notification.rb
97
85
  - lib/bullet/notification/base.rb
98
86
  - lib/bullet/notification/counter_cache.rb
@@ -125,7 +113,6 @@ files:
125
113
  - spec/bullet/registry/base_spec.rb
126
114
  - spec/bullet/registry/object_spec.rb
127
115
  - spec/bullet_spec.rb
128
- - spec/integration/active_record3/association_spec.rb
129
116
  - spec/integration/active_record4/association_spec.rb
130
117
  - spec/integration/active_record5/association_spec.rb
131
118
  - spec/integration/counter_cache_spec.rb
@@ -212,7 +199,6 @@ test_files:
212
199
  - spec/bullet/registry/base_spec.rb
213
200
  - spec/bullet/registry/object_spec.rb
214
201
  - spec/bullet_spec.rb
215
- - spec/integration/active_record3/association_spec.rb
216
202
  - spec/integration/active_record4/association_spec.rb
217
203
  - spec/integration/active_record5/association_spec.rb
218
204
  - spec/integration/counter_cache_spec.rb
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 2.5.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 2.6.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 2.7.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 2.8.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 3.0.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mongoid', '~> 3.1.0'
9
-
10
- gem "rspec"
11
-
12
- platforms :rbx do
13
- gem 'rubysl', '~> 2.0'
14
- gem 'rubinius-developer_tools'
15
- end
@@ -1,16 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.0.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'activerecord-import'
9
- gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
10
-
11
- gem "rspec"
12
-
13
- platforms :rbx do
14
- gem 'rubysl', '~> 2.0'
15
- gem 'rubinius-developer_tools'
16
- end
@@ -1,16 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.1.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'activerecord-import'
9
- gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
10
-
11
- gem "rspec"
12
-
13
- platforms :rbx do
14
- gem 'rubysl', '~> 2.0'
15
- gem 'rubinius-developer_tools'
16
- end
@@ -1,16 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rails', '~> 3.2.0'
6
- gem 'sqlite3', platforms: [:ruby]
7
- gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'activerecord-import'
9
- gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
10
-
11
- gem "rspec"
12
-
13
- platforms :rbx do
14
- gem 'rubysl', '~> 2.0'
15
- gem 'rubinius-developer_tools'
16
- end
@@ -1,238 +0,0 @@
1
- module Bullet
2
- module ActiveRecord
3
- LOAD_TARGET = 'load_target'.freeze
4
-
5
- def self.enable
6
- require 'active_record'
7
- ::ActiveRecord::Base.class_eval do
8
- class <<self
9
- alias_method :origin_find_by_sql, :find_by_sql
10
- def find_by_sql(sql)
11
- result = origin_find_by_sql(sql)
12
- if Bullet.start?
13
- if result.is_a? Array
14
- if result.size > 1
15
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
16
- Bullet::Detector::CounterCache.add_possible_objects(result)
17
- elsif result.size == 1
18
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
19
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
20
- end
21
- elsif result.is_a? ::ActiveRecord::Base
22
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
23
- Bullet::Detector::CounterCache.add_impossible_object(result)
24
- end
25
- end
26
- result
27
- end
28
- end
29
- end
30
-
31
- ::ActiveRecord::Relation.class_eval do
32
- alias_method :origin_to_a, :to_a
33
- # if select a collection of objects, then these objects have possible to cause N+1 query.
34
- # if select only one object, then the only one object has impossible to cause N+1 query.
35
- def to_a
36
- records = origin_to_a
37
- if Bullet.start?
38
- if records.size > 1
39
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
40
- Bullet::Detector::CounterCache.add_possible_objects(records)
41
- elsif records.size == 1
42
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
43
- Bullet::Detector::CounterCache.add_impossible_object(records.first)
44
- end
45
- end
46
- records
47
- end
48
- end
49
-
50
- ::ActiveRecord::Persistence.class_eval do
51
- alias_method :origin_save, :save
52
- def save(*args, &proc)
53
- was_new_record = new_record?
54
- origin_save(*args, &proc).tap do |result|
55
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
56
- end
57
- end
58
-
59
- alias_method :origin_save!, :save!
60
- def save!(*args, &proc)
61
- was_new_record = new_record?
62
- origin_save!(*args, &proc).tap do |result|
63
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self) if result && was_new_record
64
- end
65
- end
66
- end
67
-
68
- ::ActiveRecord::AssociationPreload::ClassMethods.class_eval do
69
- alias_method :origin_preload_associations, :preload_associations
70
- # include query for one to many associations.
71
- # keep this eager loadings.
72
- def preload_associations(records, associations, preload_options={})
73
- if Bullet.start?
74
- records = [records].flatten.compact.uniq
75
- return if records.empty?
76
- records.each do |record|
77
- Bullet::Detector::Association.add_object_associations(record, associations)
78
- end
79
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
80
- end
81
- origin_preload_associations(records, associations, preload_options={})
82
- end
83
- end
84
-
85
- ::ActiveRecord::FinderMethods.class_eval do
86
- # add includes in scope
87
- alias_method :origin_find_with_associations, :find_with_associations
88
- def find_with_associations
89
- records = origin_find_with_associations
90
- if Bullet.start?
91
- associations = (@eager_load_values + @includes_values).uniq
92
- records.each do |record|
93
- Bullet::Detector::Association.add_object_associations(record, associations)
94
- end
95
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
96
- end
97
- records
98
- end
99
- end
100
-
101
- ::ActiveRecord::Associations::ClassMethods::JoinDependency.class_eval do
102
- alias_method :origin_instantiate, :instantiate
103
- alias_method :origin_construct_association, :construct_association
104
-
105
- def instantiate(rows)
106
- @bullet_eager_loadings = {}
107
- records = origin_instantiate(rows)
108
-
109
- if Bullet.start?
110
- @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
111
- objects = eager_loadings_hash.keys
112
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
113
- end
114
- end
115
- records
116
- end
117
-
118
- # call join associations
119
- def construct_association(record, join, row)
120
- result = origin_construct_association(record, join, row)
121
-
122
- if Bullet.start?
123
- associations = join.reflection.name
124
- Bullet::Detector::Association.add_object_associations(record, associations)
125
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
126
- @bullet_eager_loadings[record.class] ||= {}
127
- @bullet_eager_loadings[record.class][record] ||= Set.new
128
- @bullet_eager_loadings[record.class][record] << associations
129
- end
130
-
131
- result
132
- end
133
- end
134
-
135
- ::ActiveRecord::Associations::AssociationCollection.class_eval do
136
- # call one to many associations
137
- alias_method :origin_load_target, :load_target
138
- def load_target
139
- if Bullet.start?
140
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
141
- end
142
- origin_load_target
143
- end
144
-
145
- alias_method :origin_first, :first
146
- def first(*args)
147
- if Bullet.start?
148
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
149
- end
150
- origin_first(*args)
151
- end
152
-
153
- alias_method :origin_last, :last
154
- def last(*args)
155
- if Bullet.start?
156
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
157
- end
158
- origin_last(*args)
159
- end
160
-
161
- alias_method :origin_include?, :include?
162
- def include?(object)
163
- if Bullet.start?
164
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
165
- end
166
- origin_include?(object)
167
- end
168
- end
169
-
170
- ::ActiveRecord::Associations::HasManyAssociation.class_eval do
171
- alias_method :origin_empty?, :empty?
172
- def empty?
173
- if Bullet.start? && !has_cached_counter?
174
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
175
- end
176
- origin_empty?
177
- end
178
- end
179
-
180
- ::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
181
- alias_method :origin_empty?, :empty?
182
- def empty?
183
- if Bullet.start?
184
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
185
- end
186
- origin_empty?
187
- end
188
- end
189
-
190
- ::ActiveRecord::Associations::AssociationProxy.class_eval do
191
- # call has_one and belong_to association
192
- alias_method :origin_load_target, :load_target
193
- def load_target
194
- # avoid stack level too deep
195
- result = origin_load_target
196
- if Bullet.start?
197
- Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name) unless caller.any? { |c| c.include?(LOAD_TARGET) }
198
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
199
- end
200
- result
201
- end
202
-
203
- alias_method :origin_set_inverse_instance, :set_inverse_instance
204
- def set_inverse_instance(record, instance)
205
- if Bullet.start?
206
- if record && we_can_set_the_inverse_on_this?(record)
207
- Bullet::Detector::NPlusOneQuery.add_inversed_object(record, @reflection.inverse_of.name)
208
- end
209
- end
210
- origin_set_inverse_instance(record, instance)
211
- end
212
- end
213
-
214
- ::ActiveRecord::Associations::HasManyAssociation.class_eval do
215
- alias_method :origin_has_cached_counter?, :has_cached_counter?
216
-
217
- def has_cached_counter?
218
- result = origin_has_cached_counter?
219
- if Bullet.start? && !result
220
- Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
221
- end
222
- result
223
- end
224
- end
225
-
226
- ::ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
227
- alias_method :origin_has_cached_counter?, :has_cached_counter?
228
- def has_cached_counter?
229
- result = origin_has_cached_counter?
230
- if Bullet.start? && !result
231
- Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
232
- end
233
- result
234
- end
235
- end
236
- end
237
- end
238
- end