module FetcheableOnApi::Sortable

Sortable implements `pagination` support.

Constants

SORT_ORDER

Map of symbol to sorting direction supported by the module.

Public Class Methods

included(base) click to toggle source

Public class methods

# File lib/fetcheable_on_api/sortable.rb, line 17
def self.included(base)
  base.class_eval do
    extend ClassMethods
    class_attribute :sorts_configuration, instance_writer: false
    self.sorts_configuration = {}
  end
end

Protected Instance Methods

apply_sort(collection) click to toggle source

Protected instance methods

# File lib/fetcheable_on_api/sortable.rb, line 59
def apply_sort(collection)
  return collection if params[:sort].blank?

  foa_valid_parameters!(:sort, foa_permitted_types: [String])

  ordering = format_params(params[:sort]).map do |attr_name, sort_method|
    arel_sort(attr_name, sort_method, collection)
  end

  collection.order(ordering.compact)
end

Private Instance Methods

arel_sort(attr_name, sort_method, collection) click to toggle source
# File lib/fetcheable_on_api/sortable.rb, line 73
def arel_sort(attr_name, sort_method, collection)
  return if sorts_configuration[attr_name].blank?

  klass = class_for(attr_name, collection)
  field = field_for(attr_name)
  return unless belong_to_attributes_for?(klass, field)

  attribute = klass.arel_table[field]
  attribute = attribute.lower if sorts_configuration[attr_name].fetch(:lower, false)

  attribute.send(sort_method)
end
belong_to_attributes_for?(klass, field) click to toggle source
# File lib/fetcheable_on_api/sortable.rb, line 94
def belong_to_attributes_for?(klass, field)
  klass.attribute_names.include?(field)
end
class_for(attr_name, collection) click to toggle source
# File lib/fetcheable_on_api/sortable.rb, line 86
def class_for(attr_name, collection)
  sorts_configuration[attr_name].fetch(:class_name, collection.klass)
end
field_for(attr_name) click to toggle source
# File lib/fetcheable_on_api/sortable.rb, line 90
def field_for(attr_name)
  sorts_configuration[attr_name].fetch(:as, attr_name).to_s
end
format_params(params) click to toggle source

input: “-email,first_name” return: { email: :desc, first_name: :asc }

# File lib/fetcheable_on_api/sortable.rb, line 102
def format_params(params)
  res = {}
  params
    .split(",")
    .each do |attribute|
    sort_sign = attribute =~ /\A[+-]/ ? attribute.slice!(0) : "+"
    res[attribute.to_sym] = SORT_ORDER[sort_sign]
  end
  res
end