Module: Motor::ApiQuery::Sort

Defined in:
lib/motor/api_query/sort.rb

Constant Summary collapse

FIELD_PARSE_REGEXP =
/\A(-)?(.*)\z/.freeze

Class Method Summary collapse

Class Method Details

.build_arel_order(model, param) ⇒ Object


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/motor/api_query/sort.rb', line 36

def build_arel_order(model, param)
  param.split(',').map do |field|
    direction, key = field.match(FIELD_PARSE_REGEXP).captures
    *path, field = key.split('.')

    reflection_model =
      path.reduce(model) do |acc, fragment|
        acc.reflections[fragment].klass
      end

    arel_column = reflection_model.arel_table[field]

    direction.present? ? arel_column.desc : arel_column.asc
  end
end

.build_join_params(_model, param) ⇒ Object


21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/motor/api_query/sort.rb', line 21

def build_join_params(_model, param)
  param.split(',').each_with_object({}) do |field, result|
    key = field[FIELD_PARSE_REGEXP, 2]
    *path, _ = key.split('.')

    path.reduce(result) do |acc, fragment|
      hash = {}

      acc[fragment] = hash

      hash
    end
  end
end

.call(rel, param) ⇒ Object


10
11
12
13
14
15
16
17
18
19
# File 'lib/motor/api_query/sort.rb', line 10

def call(rel, param)
  return rel if param.blank?

  arel_order = build_arel_order(rel.klass, param)
  join_params = build_join_params(rel.klass, param)

  rel = rel.left_joins(join_params) if join_params.present?

  rel.reorder(arel_order)
end