Skip to content

Commit be7410a

Browse files
authored
MONGOID-4960 Create an exception subclass for calling estimated_count on models with default scopes (#5458)
* MONGOID-4960 Create an exception subclass for calling estimated_count on models with default scopes * MONGOID-4960 add test * MONGOID-4960 use count instead
1 parent 55d1bd7 commit be7410a

File tree

5 files changed

+66
-3
lines changed

5 files changed

+66
-3
lines changed

lib/config/locales/en.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,13 @@ en:
181181
message: "Invalid criteria for estimated_count."
182182
summary: "Estimated count is strictly a collection-level operation and cannot be called
183183
on a filtered criteria."
184-
resolution: "Try calling estimated_count directly on the class: %{class_name}.estimated_count.\n\n
185-
\_If the class defines a default scope, use unscoped: %{class_name}.unscoped.estimated_count."
184+
resolution: "Try calling estimated_count directly on the class: %{class_name}.estimated_count."
185+
invalid_estimated_count_scoping:
186+
message: "Invalid criteria for estimated_count."
187+
summary: "Estimated count is strictly a collection-level operation and cannot be called
188+
on a model that uses a default scope."
189+
resolution: "Try calling estimated_count using unscoped: %{class_name}.unscoped.estimated_count.
190+
Alternatively, the #count method can be used, which is usable with scoping."
186191
invalid_expression_operator:
187192
message: "Invalid expression operator '%{operator}'."
188193
summary: "You misspelled an operator, are using an operator that

lib/mongoid/contextual/mongo.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ def count(options = {}, &block)
7373
# @return [ Integer ] The number of matches.
7474
def estimated_count(options = {})
7575
unless self.criteria.selector.empty?
76-
raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
76+
if klass.default_scoping?
77+
raise Mongoid::Errors::InvalidEstimatedCountScoping.new(self.klass)
78+
else
79+
raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
80+
end
7781
end
7882
view.estimated_document_count(options)
7983
end

lib/mongoid/errors.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
require "mongoid/errors/invalid_dot_dollar_assignment"
3030
require "mongoid/errors/invalid_elem_match_operator"
3131
require "mongoid/errors/invalid_estimated_count_criteria"
32+
require "mongoid/errors/invalid_estimated_count_scoping"
3233
require "mongoid/errors/invalid_expression_operator"
3334
require "mongoid/errors/invalid_field_operator"
3435
require "mongoid/errors/invalid_relation"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
module Mongoid
4+
module Errors
5+
6+
class InvalidEstimatedCountScoping < MongoidError
7+
8+
# Creates the exception raised when trying to call estimated_count
9+
# on Model with a default scope
10+
#
11+
# @param [ String ] class_name The klass of the criteria used to call
12+
# estimated count.
13+
#
14+
# @api private
15+
def initialize(class_name)
16+
super(
17+
compose_message(
18+
"invalid_estimated_count_scoping",
19+
{ class_name: class_name }
20+
)
21+
)
22+
end
23+
end
24+
end
25+
end

spec/mongoid/contextual/mongo_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,34 @@
223223
end
224224
end
225225
end
226+
227+
context "when including a default scope" do
228+
229+
let(:criteria) do
230+
Band.where(name: "New Order")
231+
end
232+
233+
before do
234+
5.times { Band.create! }
235+
Band.default_scope ->{ criteria }
236+
end
237+
238+
after do
239+
Band.default_scoping = nil
240+
end
241+
242+
it 'raises an error' do
243+
expect do
244+
Band.estimated_count
245+
end.to raise_error(Mongoid::Errors::InvalidEstimatedCountScoping)
246+
end
247+
248+
it "does not raise an error on unscoped" do
249+
expect do
250+
expect(Band.unscoped.estimated_count).to eq(5)
251+
end
252+
end
253+
end
226254
end
227255

228256

0 commit comments

Comments
 (0)