module Railsful::Interceptors::Sorting

Interceptor that sorts a given ActiveRecord::Relation

Public Instance Methods

render(options) click to toggle source
Calls superclass method
# File lib/railsful/interceptors/sorting.rb, line 7
def render(options)
  super(sorting_options(options))
end
sorting_options(options) click to toggle source
# File lib/railsful/interceptors/sorting.rb, line 11
def sorting_options(options)
  # Check if json value should be sorted.
  return options unless sort?(options)

  # Get the relation from options hash so we can sort it
  relation = options.fetch(:json)

  options.merge(json: sort(relation))
end

Private Instance Methods

order(string) click to toggle source

Format a sort string to a database friendly order string

@return [String] database order query e.g. 'name DESC'

:reek: UtilityFunction

# File lib/railsful/interceptors/sorting.rb, line 36
def order(string)
  string.start_with?('-') ? "#{string[1..-1]} DESC" : "#{string} ASC"
end
orders() click to toggle source

Map the sort params to a database friendly set of strings

@return [Array] Array of string e.g. ['name DESC', 'age ASC']

# File lib/railsful/interceptors/sorting.rb, line 43
def orders
  params.fetch(:sort).split(',').map do |string|
    next unless string =~ /\A-?\w+\z/ # allow only word chars

    order(string)
  end.compact
end
sort(relation) click to toggle source

Sort given relation

@param relation [ActiveRecord::Relation] The relation. @return [ActiveRecord::Relation] The sorted relation.

# File lib/railsful/interceptors/sorting.rb, line 55
def sort(relation)
  order_string = orders.join(', ')
  # support both #reorder and #order call on relation
  return relation.reorder(order_string) if relation.respond_to?(:reorder)
  return relation.order(order_string) if relation.respond_to?(:order)

  raise SortingError, 'Relation does not respond to #reorder or #order.'
end
sort?(options) click to toggle source

Check if given entity is sortable and request allows sorting.

@param options [Hash] The global render options. @return [Boolean] The answer.

# File lib/railsful/interceptors/sorting.rb, line 27
def sort?(options)
  method == 'GET' && params.fetch(:sort, false) && relation?(options)
end