Skip to content
30 changes: 30 additions & 0 deletions lib/mongoid/findable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,36 @@ def exists?(id_or_conditions = :none)
with_default_scope.exists?(id_or_conditions)
end

# Return true if any documents exist in the criteria.
#
# @example Determine if any documents exist
# criteria.any?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is an artifact from when you had this on Mongoid::Criteria, but for documentation purposes you can just reference Model, generically.

Suggested change
# criteria.any?
# Model.any?

Ditto for the other new methods you added.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

#
# @return [ true | false ] If any documents exist.
def any?(*args, &block)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's safe to leave off the *args and &block here, since they aren't used in the method body anymore.

Ditto for the other two methods you added. 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

limit(1).count > 0
end

# Return true if only one document exists in the criteria.
#
# @example Determine if only one document exists
# criteria.one?
#
# @return [ true | false ] If only one document exists.
def one?(*args, &block)
limit(2).count == 1
end

# Return true if more than one document exists in the criteria.
#
# @example Determine if many documents exist
# criteria.many?
#
# @return [ true | false ] If many documents exist.
def many?(*args, &block)
limit(2).count > 1
end

# Finds a +Document+ or multiple documents by their _id values.
#
# If a single non-Array argument is given, this argument is interpreted
Expand Down
195 changes: 195 additions & 0 deletions spec/mongoid/criteria/findable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,201 @@
end
end

describe "#any?" do
context "when called on criteria" do
let!(:band) do
Band.create!(name: "Depeche Mode")
end

let!(:band_two) do
Band.create!(name: "Radiohead")
end

context "when documents exist" do

let(:criteria) do
Band.all
end

it "returns true" do
expect(criteria.any?).to be true
end
end

context "when no documents exist" do

let(:criteria) do
Band.where(name: "Nonexistent Band")
end

it "returns false" do
expect(criteria.any?).to be false
end
end
end

context "when called on class" do
context "with documents" do
before do
Band.create!(name: "New Band")
end

it "returns true" do
expect(Band.any?).to be true
end
end

context "with no documents" do
it "returns false" do
expect(Band.any?).to be false
end
end
end
end

describe "#one?" do
context "when called on criteria" do
let!(:band) do
Band.create!(name: "Depeche Mode")
end

let!(:band_two) do
Band.create!(name: "Radiohead")
end

context "when one document exists in criteria" do
let(:criteria) do
Band.where(name: "Depeche Mode")
end

it "returns true" do
expect(criteria.one?).to be true
end
end

context "when multiple documents exist in criteria" do
let(:criteria) do
Band.all
end

it "returns false" do
expect(criteria.one?).to be false
end
end

context "when no documents exist in criteria" do
let(:criteria) do
Band.where(name: "Nonexistent Band")
end

it "returns false" do
expect(criteria.one?).to be false
end
end
end

context "when called on class" do
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me know if this needs to be moved elsewhere or isnt needed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this should probably be moved to spec/mongoid/findable_spec.rb, since it's no longer implemented on Mongoid::Criteria.

When you move these, you should also make sure the tests invoke the new methods directly on the model classes, rather than on criteria instances. E.g.

let(:model) { Band } # instance of :criteria

# ...

expect(model.any?).to be true

context "with no documents" do
it "returns false" do
expect(Band.one?).to be false
end
end

context "with one document" do
before do
Band.create!(name: "Another Band")
end

it "returns true" do
expect(Band.one?).to be true
end
end

context "with multiple documents" do
before do
Band.create!(name: "New Band")
Band.create!(name: "Yet Another Band")
end

it "returns false" do
expect(Band.one?).to be false
end
end
end
end

describe "#many?" do
context "when called on criteria" do
let!(:band) do
Band.create!(name: "Depeche Mode")
end

let!(:band_two) do
Band.create!(name: "Radiohead")
end

context "when multiple documents exist in criteria" do
let(:criteria) do
Band.all
end

it "returns true" do
expect(criteria.many?).to be true
end
end

context "when one document exists in criteria" do
let(:criteria) do
Band.where(name: "Depeche Mode")
end

it "returns false" do
expect(criteria.many?).to be false
end
end

context "when no documents exist in criteria" do
let(:criteria) do
Band.where(name: "Nonexistent Band")
end

it "returns false" do
expect(criteria.many?).to be false
end
end

end

context "when called on class" do
context "with no documents" do
it "returns false" do
expect(Band.many?).to be false
end
end

context "with one document" do
before do
Band.create!(name: "Another Band")
end

it "returns false" do
expect(Band.many?).to be false
end
end

context "with multiple documents" do
before do
Band.create!(name: "New Band")
Band.create!(name: "Yet Another Band")
end

it "returns true" do
expect(Band.many?).to be true
end
end
end
end

describe '#from_database_selector' do
let(:criteria) { Mongoid::Criteria.new(Band) }
let(:result) { criteria.send(:from_database_selector, [1]) }
Expand Down
Loading