Skip to content

Commit b603a2b

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

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/mongoid/contextual/mongo.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,14 @@ def cached?
6565
# @return [ Integer ] The number of matches.
6666
def count(options = {}, &block)
6767
return super(&block) if block_given?
68-
try_cache(:count) { view.count_documents(options) }
68+
69+
try_cache(:count) do
70+
if valid_for_count_documents?
71+
view.count_documents(options)
72+
else
73+
view.count(options)
74+
end
75+
end
6976
end
7077

7178
# Get the estimated number of documents matching the query.
@@ -902,6 +909,24 @@ def process_raw_docs(raw_docs, limit)
902909
docs = eager_load(docs)
903910
limit ? docs : docs.first
904911
end
912+
913+
# Queries whether the current context is valid for use with
914+
# the #count_documents? predicate. A context is valid if it
915+
# does not include a `$where` operator.
916+
#
917+
# @return [ true | false ] whether or not the current context
918+
# excludes a `$where` operator.
919+
def valid_for_count_documents?(hash = view.filter)
920+
# Note that `view.filter` is a BSON::Document, and all keys in a
921+
# BSON::Document are strings; we don't need to worry about symbol
922+
# representations of `$where`.
923+
hash.keys.each do |key|
924+
return false if key == '$where'
925+
return false if hash[key].is_a?(Hash) && !valid_for_count_documents?(hash[key])
926+
end
927+
928+
true
929+
end
905930
end
906931
end
907932
end

spec/mongoid/contextual/mongo_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@
189189
end
190190
end
191191
end
192+
193+
context 'when for_js is present' do
194+
let(:context) do
195+
Band.for_js('this.name == "Depeche Mode"')
196+
end
197+
198+
it 'counts the expected records' do
199+
expect(context.count).to eq(1)
200+
end
201+
end
192202
end
193203

194204
describe "#estimated_count" do

0 commit comments

Comments
 (0)