lib/mongoid/contextual/mongo.rb in mongoid-7.5.2 vs lib/mongoid/contextual/mongo.rb in mongoid-7.5.3

- old
+ new

@@ -258,20 +258,20 @@ # @option limit_or_opts [ :none ] :id_sort This option is deprecated. # Don't apply a sort on _id if no other sort is defined on the criteria. # # @return [ Document ] The first document. def first(limit_or_opts = nil) - limit = limit_or_opts unless limit_or_opts.is_a?(Hash) + limit, opts = extract_limit_and_opts(limit_or_opts) if cached? && cache_loaded? return limit ? documents.first(limit) : documents.first end try_numbered_cache(:first, limit) do - if limit_or_opts.try(:key?, :id_sort) + if opts.key?(:id_sort) Mongoid::Warnings.warn_id_sort_deprecated end sorted_view = view - if sort = view.sort || ({ _id: 1 } unless limit_or_opts.try(:fetch, :id_sort) == :none) + if sort = view.sort || ({ _id: 1 } unless opts[:id_sort] == :none) sorted_view = view.sort(sort) end if raw_docs = sorted_view.limit(limit || 1).to_a process_raw_docs(raw_docs, limit) end @@ -374,16 +374,16 @@ # @option limit_or_opts [ :none ] :id_sort This option is deprecated. # Don't apply a sort on _id if no other sort is defined on the criteria. # # @return [ Document ] The last document. def last(limit_or_opts = nil) - limit = limit_or_opts unless limit_or_opts.is_a?(Hash) + limit, opts = extract_limit_and_opts(limit_or_opts) if cached? && cache_loaded? return limit ? documents.last(limit) : documents.last end res = try_numbered_cache(:last, limit) do - with_inverse_sorting(limit_or_opts) do + with_inverse_sorting(opts) do if raw_docs = view.limit(limit || 1).to_a process_raw_docs(raw_docs, limit) end end end @@ -610,10 +610,27 @@ ret end end end + # Extract the limit and opts from the given argument, so that code + # can operate without having to worry about the current type and + # state of the argument. + # + # @param [ nil | Integer | Hash ] limit_or_opts The value to pull the + # limit and option hash from. + # + # @return [ Array<nil | Integer, Hash> ] A 2-array of the limit and the + # option hash. + def extract_limit_and_opts(limit_or_opts) + case limit_or_opts + when nil, Integer then [ limit_or_opts, {} ] + when Hash then [ nil, limit_or_opts ] + else raise ArgumentError, "expected nil, Integer, or Hash" + end + end + # Update the documents for the provided method. # # @api private # # @example Update the documents. @@ -674,13 +691,13 @@ # @api private # # @example Apply the inverse sorting params to the given block # context.with_inverse_sorting def with_inverse_sorting(opts = {}) - Mongoid::Warnings.warn_id_sort_deprecated if opts.try(:key?, :id_sort) + Mongoid::Warnings.warn_id_sort_deprecated if opts.key?(:id_sort) begin - if sort = criteria.options[:sort] || ( { _id: 1 } unless opts.try(:fetch, :id_sort) == :none ) + if sort = criteria.options[:sort] || ( { _id: 1 } unless opts[:id_sort] == :none ) @view = view.sort(Hash[sort.map{|k, v| [k, -1*v]}]) end yield ensure apply_option(:sort)