module Ants::SortedRelations

Public Instance Methods

define_has_and_belongs_to_many_sorted_methods(relation) click to toggle source

HAS_AND_BELONGS_TO_MANY

# File lib/concerns/ants/sorted_relations.rb, line 56
def define_has_and_belongs_to_many_sorted_methods(relation)
  # sorted_#{ relation.name }
  self.send(:define_method, "sorted_#{ relation.name }") do
    related_documents   = self.send(relation.name)
    sorted_relation_ids = self.send("#{ relation.name.to_s.singularize }_ids").map { |id| id.to_s }

    sorted_documents = related_documents.sort_by do |document|
      sorted_relation_ids.index(document.id.to_s) || -1
    end

    return Mongoid::FakeCriteria.new(sorted_documents)
  end

  # sorted_#{ relation.name } = [ <array of ids> ]
  self.send(:define_method, "sorted_#{ relation.name.to_s.singularize }_ids=") do |ids|
    self.send("#{ relation.name.to_s.singularize }_ids=", ids)
  end
end
define_has_many_sorted_methods(relation) click to toggle source

HAS_MANY

# File lib/concerns/ants/sorted_relations.rb, line 79
def define_has_many_sorted_methods(relation)
  # define field to store order for has_many related documents
  self.field "_sorted_#{ relation.name.to_s.singularize }_ids", :type => Array, default: []

  # sorted_#{ relation.name }
  self.send(:define_method, "sorted_#{ relation.name }") do
    related_documents   = self.send(relation.name)
    sorted_relation_ids = self["_sorted_#{ relation.name.to_s.singularize }_ids"].map { |id| id.to_s }

    # missing or new ids are in random order
    sorted_documents = related_documents.sort_by do |document|
      sorted_relation_ids.index(document.id.to_s) || -1
    end

    return Mongoid::FakeCriteria.new(sorted_documents)
  end

  # sorted_#{ relation.name } = [ <array of ids> ]
  self.send(:define_method, "sorted_#{ relation.name.to_s.singularize }_ids=") do |ids|
    ids = ids.map{ |id| id.to_s }

    self.update_attributes({
      "_sorted_#{ relation.name.to_s.singularize }_ids" => ids, # store order
      "#{ relation.name.to_s.singularize }_ids"         => ids  # update relations
    })
  end
end
sorted_relations_for(relation_name) click to toggle source
# File lib/concerns/ants/sorted_relations.rb, line 40
def sorted_relations_for(relation_name)
  relation = self.relations[relation_name.to_s]

  if relation.macro == :has_and_belongs_to_many
    define_has_and_belongs_to_many_sorted_methods(relation)
  end

  if relation.macro == :has_many
    define_has_many_sorted_methods(relation)
  end
end