module CustomFields::Types::ManyToMany::Target::ClassMethods

Public Instance Methods

_naturally_ordered(criteria, _order_by = nil) click to toggle source
# File lib/custom_fields/types/many_to_many.rb, line 46
def _naturally_ordered(criteria, _order_by = nil)
  # use the natural order given by the initial array (ex: project_ids).
  # Warning: it returns an array and not a criteria object meaning it breaks the chain
  ids = _base.send(_association.name.to_sym)
  criteria.entries.sort { |a, b| ids.index(a.id) <=> ids.index(b.id) }
end
apply_many_to_many_custom_field(klass, rule) click to toggle source

Adds a many_to_many relationship between 2 mongoid models

@param [ Class ] klass The class to modify @param [ Hash ] rule It contains the name of the relation and if it is required or not

# File lib/custom_fields/types/many_to_many.rb, line 29
def apply_many_to_many_custom_field(klass, rule)
  # puts "#{klass.inspect}.many_to_many #{rule['name'].inspect}, class_name: #{rule['class_name'].inspect} / #{rule['order_by']}" # DEBUG

  klass.has_and_belongs_to_many rule['name'], class_name: rule['class_name'], inverse_of: rule['inverse_of'],
                                              validate: false, order: rule['order_by'] do
    def filtered(conditions = {}, order_by = nil)
      list = conditions.empty? ? self : where(conditions)

      if order_by
        list.order_by(order_by)
      else
        _naturally_ordered(list, order_by)
      end
    end

    alias_method :ordered, :filtered # backward compatibility + semantic purpose

    def _naturally_ordered(criteria, _order_by = nil)
      # use the natural order given by the initial array (ex: project_ids).
      # Warning: it returns an array and not a criteria object meaning it breaks the chain
      ids = _base.send(_association.name.to_sym)
      criteria.entries.sort { |a, b| ids.index(a.id) <=> ids.index(b.id) }
    end

    def pluck_with_natural_order(*attributes)
      criteria = only([:_id] + [*attributes])
      _naturally_ordered(criteria).map do |entry|
        if attributes.size == 1
          entry.public_send(attributes.first.to_sym)
        else
          attributes.map { |name| entry.public_send(name.to_sym) }
        end
      end
    end
  end

  return unless rule['required']

  klass.validates_collection_size_of rule['name'], minimum: 1, message: :at_least_one_element
end
filtered(conditions = {}, order_by = nil) click to toggle source
# File lib/custom_fields/types/many_to_many.rb, line 34
def filtered(conditions = {}, order_by = nil)
  list = conditions.empty? ? self : where(conditions)

  if order_by
    list.order_by(order_by)
  else
    _naturally_ordered(list, order_by)
  end
end
pluck_with_natural_order(*attributes) click to toggle source
# File lib/custom_fields/types/many_to_many.rb, line 53
def pluck_with_natural_order(*attributes)
  criteria = only([:_id] + [*attributes])
  _naturally_ordered(criteria).map do |entry|
    if attributes.size == 1
      entry.public_send(attributes.first.to_sym)
    else
      attributes.map { |name| entry.public_send(name.to_sym) }
    end
  end
end