Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MONGOID-5608 - Allow exists? on relations #91

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/release-notes/mongoid-9.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ Bug Fixes and Improvements

This section will be for smaller bug fixes and improvements:

- The ``exists?`` method on relations now accepts the same arguments
as ``Criteria#exists?``.
`MONGOID-5608 <https://jira.mongodb.org/browse/MONGOID-5608>`_.
- Calling ``exists?`` on an embedded relation nil now return ``false``
when the relation is not persisted in the database.
`MONGOID-5610 <https://jira.mongodb.org/browse/MONGOID-5610>`_.
- The ``.tally`` method can now take a keyword arg :unwind
which tallies array values individually (using the ``$unwind`` operator.)
`MONGOID-5556 <https://jira.mongodb.org/browse/MONGOID-5556>`_.
Expand Down
17 changes: 2 additions & 15 deletions lib/mongoid/association/embedded/embeds_many/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class EmbedsMany
class Proxy < Association::Many
include Batchable

def_delegator :criteria, :exists?

# Appends a document or array of documents to the association. Will set
# the parent and update the index in the process.
#
Expand Down Expand Up @@ -212,21 +214,6 @@ def destroy_all(conditions = {})
remove_all(conditions, :destroy)
end

# Determine if any documents in this association exist in the database.
#
# @example Are there persisted documents?
# person.posts.exists?
#
# @param [ Hash | Object | false ] id_or_conditions an _id to
# search for, a hash of conditions, nil or false.
#
# @return [ true | false ] True is persisted documents exist, false if not.
def exists?(id_or_conditions = :none)
return _target.any?(&:persisted?) if id_or_conditions == :none

criteria.exists?(id_or_conditions)
end

# Finds a document in this association through several different
# methods.
#
Expand Down
22 changes: 1 addition & 21 deletions lib/mongoid/association/referenced/has_many/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class HasMany
class Proxy < Association::Many
extend Forwardable

def_delegator :criteria, :count
def_delegators :criteria, :count, :exists?
def_delegators :_target, :first, :in_memory, :last, :reset, :uniq

# Appends a document or array of documents to the association. Will set
Expand Down Expand Up @@ -163,26 +163,6 @@ def each(&block)
end
end

# Determine if any documents in this association exist in the database.
#
# If the association contains documents but all of the documents
# exist only in the application, i.e. have not been persisted to the
# database, this method returns false.
#
# This method queries the database on each invocation even if the
# association is already loaded into memory.
#
# @example Are there persisted documents?
# person.posts.exists?
#
# @param [ Hash | Object | false ] id_or_conditions an _id to
# search for, a hash of conditions, nil or false.
#
# @return [ true | false ] True is persisted documents exist, false if not.
def exists?(id_or_conditions = :none)
criteria.exists?(id_or_conditions)
end

# Find the matching document on the association, either based on id or
# conditions.
#
Expand Down
11 changes: 8 additions & 3 deletions lib/mongoid/contextual/memory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,19 @@ def each(&block)
# @example Do any documents exist for given conditions.
# context.exists?(name: "...")
#
# @param [ Hash | Object | false ] id_or_conditions an _id to
# search for, a hash of conditions, nil or false.
# @example Always return false.
# context.exists?(false)
#
# @param [ :none | Hash | BSON::ObjectId | nil | false ] id_or_conditions
# May optionally supply search conditions as a hash or an object id.
# Will always return false when given nil or false. The symbol :none is
# the default when argument is not supplied.
#
# @return [ true | false ] If the count is more than zero.
# Always false if passed nil or false.
def exists?(id_or_conditions = :none)
case id_or_conditions
when :none then any?
when :none then any?(&:persisted?)
when nil, false then false
when Hash then Memory.new(criteria.where(id_or_conditions)).exists?
else Memory.new(criteria.where(_id: id_or_conditions)).exists?
Expand Down
9 changes: 7 additions & 2 deletions lib/mongoid/contextual/mongo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,16 @@ def each(&block)
# @example Do any documents exist for given conditions.
# context.exists?(name: "...")
#
# @example Always return false.
# context.exists?(false)
#
# @note We don't use count here since Mongo does not use counted
# b-tree indexes.
#
# @param [ Hash | Object | false ] id_or_conditions an _id to
# search for, a hash of conditions, nil or false.
# @param [ :none | Hash | BSON::ObjectId | nil | false ] id_or_conditions
# May optionally supply search conditions as a hash or an object id.
# Will always return false when given nil or false. The symbol :none is
# the default when argument is not supplied.
#
# @return [ true | false ] If the count is more than zero.
# Always false if passed nil or false.
Expand Down
9 changes: 6 additions & 3 deletions lib/mongoid/contextual/none.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def each(&block)
end
end

# Do any documents exist for the context.
# Do any documents exist for the null context.
#
# @example Do any documents exist in the null context.
# context.exists?
Expand All @@ -68,8 +68,11 @@ def each(&block)
# @example Do any documents exist for given conditions.
# context.exists?(name: "...")
#
# @param [ Hash | Object | false ] _id_or_conditions An _id to
# search for, a hash of conditions, nil or false.
# @example Always return false.
# context.exists?(false)
#
# @param [ :none | Hash | BSON::ObjectId | nil | false ] _id_or_conditions
# Not used in null context.
#
# @return [ false ] Always false.
def exists?(_id_or_conditions = :none)
Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid/contextual/queryable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module Queryable
#
# @return [ true | false ] If the context is empty.
def blank?
!exists?
!any?
end
alias_method :empty?, :blank?
end
Expand Down
9 changes: 7 additions & 2 deletions lib/mongoid/findable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,13 @@ def empty?
# @example Do any documents exist for given conditions.
# Person.exists?(name: "...")
#
# @param [ Hash | Object | false ] id_or_conditions an _id to
# search for, a hash of conditions, nil or false.
# @example Always return false.
# context.exists?(false)
#
# @param [ :none | Hash | BSON::ObjectId | nil | false ] id_or_conditions
# May optionally supply search conditions as a hash or an object id.
# Will always return false when given nil or false. The symbol :none is
# the default when argument is not supplied.
#
# @return [ true | false ] If any documents exist for the conditions.
# Always false if passed nil or false.
Expand Down
Loading