Module: Filterable::Sortable

Defined in:
lib/filterable/sortable.rb

Overview

Orders a relation from a comma-separated filters[sort] list, each term optionally prefixed with +/- for asc/desc. Only attributes the model declared sortable are honored; unknown ones are skipped.

Constant Summary collapse

DIRECTIONS =
{ '+' => :asc, '-' => :desc }.freeze

Class Method Summary collapse

Class Method Details

.call(params, scope) ⇒ ActiveRecord::Relation?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Orders the scope from the comma-separated filters[sort] list, honoring only declared sortable attributes.

Parameters:

  • params (Hash, ActionController::Parameters)

    the nested filters params.

  • scope (ActiveRecord::Relation)

    the relation being ordered.

Returns:

  • (ActiveRecord::Relation, nil)

    the ordered relation, or nil when there is no sort term.



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/filterable/sortable.rb', line 19

def call(params, scope)
  return unless params[:sort].is_a?(String)

  params[:sort].split(',').reduce(scope) do |sorted, term|
    sign, name = split_direction(term.strip)
    column = scope.sortable_attribute_names[name]
    next sorted unless column

    sorted.order(column => DIRECTIONS[sign])
  end
end

.split_direction(term) ⇒ Array(String, String)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Splits a sort term into its direction sign and attribute name, defaulting to ascending when no sign is present.

Parameters:

  • term (String)

    a single sort term, e.g. "-value_date".

Returns:

  • (Array(String, String))

    the sign (+"+"+ or "-") and the attribute name.



37
38
39
40
41
# File 'lib/filterable/sortable.rb', line 37

def split_direction(term)
  return [term[0], term[1..]] if term.start_with?('+', '-')

  ['+', term]
end