Class: RESTFramework::ModelOrderingFilter

Inherits:
BaseFilter
  • Object
show all
Defined in:
lib/rest_framework/filters.rb

Overview

A filter backend which handles ordering of the recordset.

Instance Method Summary collapse

Methods inherited from BaseFilter

#initialize

Constructor Details

This class inherits a constructor from RESTFramework::BaseFilter

Instance Method Details

#_get_fieldsObject

Get a list of ordering fields for the current action. Do not fallback to columns in case the user wants to order by a virtual column.



81
82
83
84
85
# File 'lib/rest_framework/filters.rb', line 81

def _get_fields
  return @_get_fields ||= (
    @controller.class.ordering_fields || @controller.get_fields
  )&.map(&:to_s)
end

#_get_orderingObject

Convert ordering string to an ordering configuration.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rest_framework/filters.rb', line 88

def _get_ordering
  return nil if @controller.class.ordering_query_param.blank?

  @associations = []

  # Ensure ordering_fields are strings since the split param will be strings.
  fields = self._get_fields
  order_string = @controller.params[@controller.class.ordering_query_param]

  if order_string.present?
    ordering = {}.with_indifferent_access
    order_string.split(",").each do |field|
      if field[0] == "-"
        column = field[1..-1]
        direction = :desc
      else
        column = field
        direction = :asc
      end
      next unless !fields || column.in?(fields)

      # Populate any `@associations` so the caller can include them.
      if match = /(.*)\.(.*)/.match(column)
        association, sub_field = match[1..2]
        @associations << association.to_sym

        # Also, due to Rails weirdness, we need to convert the association name to the table name.
        table_name = @controller.class.get_model.reflections[association].table_name
        column = "#{table_name}.#{sub_field}"
      end

      ordering[column] = direction
    end
    return ordering
  end

  return nil
end

#get_filtered_data(data) ⇒ Object

Order data according to the request query parameters.



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rest_framework/filters.rb', line 128

def get_filtered_data(data)
  ordering = self._get_ordering
  reorder = !@controller.class.ordering_no_reorder

  if ordering && !ordering.empty?
    # Include any associations.
    data = data.includes(*@associations) unless @associations.empty?

    return data.send(reorder ? :reorder : :order, ordering)
  end

  return data
end