mathieulaporte
7/7/2014 - 3:02 PM

mongoid_document.rb

require 'spec_helper'

class TestDocument
  include Mongoid::Document

  field :published, type: Boolean
  scope :published, -> { where(published: true) }
end

describe Mongoid::Document do
  describe "find_ordered" do
    it "returns items sorted by id" do
      item1 = TestDocument.create!
      item2 = TestDocument.create!
      TestDocument.find_ordered([item1.id, item2.id]).should eq [item1, item2]
      TestDocument.find_ordered([item2.id, item1.id]).should eq [item2, item1]
    end

    it "returns items by criteria sorted by id" do
      item1 = TestDocument.create!(published: true)
      item2 = TestDocument.create!(published: false)
      item3 = TestDocument.create!(published: true)
      TestDocument.find_ordered([item1.id, item2.id, item3.id], TestDocument.published).should eq [item1, item3]
      TestDocument.find_ordered([item3.id, item2.id, item1.id], TestDocument.published).should eq [item3, item1]
    end
  end
end
require 'garner'

module Mongoid
  module Document
    module ClassMethods
      # Find instances by ID or crtieria in the same order as the IDs provided.
      # TODO: this can be done with an $or until MongoDB 2.6, see https://jira.mongodb.org/browse/SERVER-14083
      def find_ordered(ids, criteria = nil)
        return [] if ids.empty?
        instances = criteria || self.find(ids)
        instances_map = Hash[instances.map { |instance| [instance.id, instance] }]
        ids.map { |id| instances_map[id] }.compact
      end
    end
  end
end