Module: Order

Defined in:
lib/order.rb,
lib/order/version.rb

Defined Under Namespace

Modules: Version

Constant Summary collapse

DIRECTION_DESC =
/\Adesc/i

Instance Method Summary collapse

Instance Method Details

#normalize_direction(direction) ⇒ Object

Converts a direction into either “ASC” or “DESC”. It uses DIRECTION_DESC to match the String.



63
64
65
# File 'lib/order.rb', line 63

def normalize_direction(direction)
  (direction =~ DIRECTION_DESC) ? 'DESC' : 'ASC'
end

#order_by(ordering) ⇒ Object

Given and ordering such as “state.desc,site,name.descending”, it orders the results as such using the order_by_* scopes.



9
10
11
12
13
14
# File 'lib/order.rb', line 9

def order_by(ordering)
  ordering.split(',').inject(self) do |relation, orderer|
    attribute, direction = *orderer.split('.')
    relation.send "order_by_#{attribute.strip}", direction
  end
end

#order_clause(attribute, direction) ⇒ Object

Builds an ordering clause string such as “some_table.some_attribute DESC”. The direction will be normalized to either “ASC” or “DESC”.



58
59
60
# File 'lib/order.rb', line 58

def order_clause(attribute, direction)
  "\"#{attribute || name}\" #{normalize_direction direction}"
end

#order_scope(name, attribute = nil, &block) ⇒ Object

Adds an order_by_(name) scope. Optionally you can provide an attribute to order on in case the name is to be an alias for the ordering. You may also provide a block that defines a custom ordering strategy.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/order.rb', line 41

def order_scope(name, attribute = nil, &block)
  scope "order_by_#{name}", lambda{ |*arguments|
    direction = arguments.first
    if block_given?
      yield normalize_direction(direction)
    else
      if attribute.is_a? Array
        order attribute.map{ |bute| order_clause bute, direction }.join ', '
      else
        order order_clause attribute || name, direction
      end
    end
  }
end

#orderable(*attribute_names) ⇒ Object #orderable(attribute_map) ⇒ Object #orderable(order_name, &block) ⇒ Object

Generates order_by_* scopes used for ordering resulting records.

Examples:

Custom ordering strategy

orderable(:category_name){ |direction| joins(:category).order "category.name #{direction}" }

Overloads:

  • #orderable(*attribute_names) ⇒ Object

    Generates simple ordering scopes that can accept a direction such as “desc”

    Parameters:

    • of (Array)

      attribute names

  • #orderable(attribute_map) ⇒ Object

    Generates simple ordering scope using aliased mapping to one or more attributes

    Parameters:

    • mapping (Hash)

      ordering name to attribute(s)

  • #orderable(order_name, &block) ⇒ Object

    Generates an ordering scope using a custom strategy specified by the given block



27
28
29
30
31
32
33
34
35
36
# File 'lib/order.rb', line 27

def orderable(*attributes, &block)
  if block_given?
    raise ArgumentError.new('Cannot provide mapped naming for custom ordering strategy') if attributes.first.is_a? Hash
    order_scope attributes.first, &block
  elsif attributes.first.is_a? Hash
    attributes.first.each{ |name, attribute| order_scope name, attribute }
  else
    attributes.each{ |attribute| order_scope attribute }
  end
end