Skip to content

Commit cce6785

Browse files
authored
MONGOID-5647 Allow #count to be used with #for_js (#5693)
* MONGOID-5647 Allow #count to be used with #for_js * look for $where in nested hashes * fix typo in method name
1 parent 2840061 commit cce6785

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lib/mongoid/contextual/mongo.rb

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ class Mongo
7474
# @return [ Integer ] The number of matches.
7575
def count(options = {}, &block)
7676
return super(&block) if block_given?
77-
view.count_documents(options)
77+
78+
if valid_for_count_documents?
79+
view.count_documents(options)
80+
else
81+
view.count(options)
82+
end
7883
end
7984

8085
# Get the estimated number of documents matching the query.
@@ -1038,6 +1043,24 @@ def process_raw_docs(raw_docs, limit)
10381043
limit ? docs : docs.first
10391044
end
10401045

1046+
# Queries whether the current context is valid for use with
1047+
# the #count_documents? predicate. A context is valid if it
1048+
# does not include a `$where` operator.
1049+
#
1050+
# @return [ true | false ] whether or not the current context
1051+
# excludes a `$where` operator.
1052+
def valid_for_count_documents?(hash = view.filter)
1053+
# Note that `view.filter` is a BSON::Document, and all keys in a
1054+
# BSON::Document are strings; we don't need to worry about symbol
1055+
# representations of `$where`.
1056+
hash.keys.each do |key|
1057+
return false if key == '$where'
1058+
return false if hash[key].is_a?(Hash) && !valid_for_count_documents?(hash[key])
1059+
end
1060+
1061+
true
1062+
end
1063+
10411064
def raise_document_not_found_error
10421065
raise Errors::DocumentNotFound.new(klass, nil, nil)
10431066
end

spec/mongoid/contextual/mongo_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,16 @@
159159
end
160160
end
161161
end
162+
163+
context 'when for_js is present' do
164+
let(:context) do
165+
Band.for_js('this.name == "Depeche Mode"')
166+
end
167+
168+
it 'counts the expected records' do
169+
expect(context.count).to eq(1)
170+
end
171+
end
162172
end
163173

164174
describe "#estimated_count" do

0 commit comments

Comments
 (0)