lib/mongoid/errors/document_not_found.rb
# frozen_string_literal: true
# rubocop:todo all
module Mongoid
module Errors
# Raised when querying the database for a document by a specific id or by
# set of attributes which does not exist. If multiple ids were passed then
# it will display all of those.
class DocumentNotFound < MongoidError
attr_reader :klass, :params
# Create the new error.
#
# @example Create the error.
# DocumentNotFound.new(Person, ["1", "2"])
#
# @example Create the error with attributes instead of ids
# DocumentNotFound.new(Person, :ssn => "1234", :name => "Helen")
#
# @param [ Class ] klass The model class.
# @param [ Hash | Array | Object ] params The attributes or ids.
# @param [ Array | Hash ] unmatched The unmatched ids, if appropriate. If
# there is a shard key this will be a hash.
def initialize(klass, params, unmatched = nil)
if !unmatched && !params.is_a?(Hash)
unmatched = Array(params) if params
end
@klass, @params = klass, params
super(
compose_message(
message_key(params, unmatched),
{
klass: klass.name,
searched: searched(params),
attributes: params,
total: total(params),
missing: missing(unmatched),
shard_key: shard_key(unmatched)
}
)
)
end
private
# Get the string to display the document params that were unmatched.
#
# @example Get the missing string.
# error.missing(1)
#
# @param [ Object | Array ] unmatched The ids that did not match.
#
# @return [ String ] The missing string.
def missing(unmatched)
if unmatched.is_a?(::Array)
unmatched.join(", ")
elsif unmatched.is_a?(::Hash)
unmatched[:_id] || unmatched["_id"]
else
unmatched
end
end
# Get the string to display the document params that were searched for.
#
# @example Get the searched string.
# error.searched(1)
#
# @param [ Object | Array ] params The ids that were searched for.
#
# @return [ String ] The searched string.
def searched(params)
if params.is_a?(::Array)
params.take(3).join(", ") + " ..."
else
params
end
end
# Get the total number of expected documents.
#
# @example Get the total.
# error.total([ 1, 2, 3 ])
#
# @param [ Object | Array ] params What was searched for.
#
# @return [ Integer ] The total number.
def total(params)
params.is_a?(::Array) ? params.count : 1
end
# Create the problem.
#
# @example Create the problem.
# error.problem
#
# @return [ String ] The problem.
def message_key(params, unmatched)
if !params && !unmatched
"no_documents_found"
elsif Hash === params
"document_with_attributes_not_found"
elsif Hash === unmatched && unmatched.size >= 2
"document_with_shard_key_not_found"
else
"document_not_found"
end
end
# Get the shard key from the unmatched hash.
#
# @return [ String ] the shard key and value.
def shard_key(unmatched)
if Hash === unmatched
h = unmatched.dup
h.delete("_id")
h.delete(:_id)
h.map{|k,v| "#{k}: #{v}" }.join(", ")
end
end
end
end
end