Skip to content

Instantly share code, notes, and snippets.

@dblock
Last active August 29, 2015 14:01
Show Gist options
  • Save dblock/d5ed835f0147467a6a27 to your computer and use it in GitHub Desktop.
Save dblock/d5ed835f0147467a6a27 to your computer and use it in GitHub Desktop.
Find objects in the same sort order as the IDs provided
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
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
@joeyAghion
Copy link

Slightly shorter:

self.in(_id: ids).sort_by { |d| ids.index(d.id) }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment