Module: JSONAPIonify::Api::Resource::Definitions::Sorting

Defined in:
lib/jsonapionify/api/resource/definitions/sorting.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(klass) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/jsonapionify/api/resource/definitions/sorting.rb', line 8

def self.extended(klass)
  klass.class_eval do
    inherited_hash_attribute :sorting_strategies
    delegate :sort_fields_from_sort_string, to: :class

    # Define Contexts
    context :sorted_collection, readonly: true do |context, collection:, sort_params:, nested_request: false|
      if !nested_request
        _, block = sorting_strategies.to_a.reverse.to_h.find do |mod, _|
          Object.const_defined?(mod, false) && collection.class <= Object.const_get(mod, false)
        end
        context.reset(:sort_params)
        instance_exec(collection, sort_params, context, &block.destructure)
      else
        collection
      end
    end

    context(:sort_params, readonly: true, persisted: true) do |params:|
      sort_fields_from_sort_string(params['sort'])
    end

    define_sorting_strategy('Object') do |collection|
      collection
    end

    define_sorting_strategy('Enumerable') do |collection, fields|
      collection.to_a.deep_sort(fields.to_h)
    end

    define_sorting_strategy('ActiveRecord::Relation') do |collection, fields|
      collection.reorder(fields.to_h).order(self.class.id_attribute)
    end

  end
end

Instance Method Details

#default_sort(options) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/jsonapionify/api/resource/definitions/sorting.rb', line 49

def default_sort(options)
  string =
    case options
    when Hash, Array
      options.map do |k, v|
        v.to_s.downcase == 'asc' ? "-#{k}" : k.to_s
      end.join(',')
    else
      options.to_s
    end
  param :sort, default: string
end

#define_sorting_strategy(mod, &block) ⇒ Object



45
46
47
# File 'lib/jsonapionify/api/resource/definitions/sorting.rb', line 45

def define_sorting_strategy(mod, &block)
  sorting_strategies[mod.to_s] = block
end

#sort_attrs_from_sort(sort_string) ⇒ Object



62
63
64
65
66
67
# File 'lib/jsonapionify/api/resource/definitions/sorting.rb', line 62

def sort_attrs_from_sort(sort_string)
  sort_attrs = sort_string.split(',').map do |a|
    a == 'id' ? id_attribute.to_s : a.to_s
  end
  sort_attrs.uniq
end

#sort_fields_from_sort_string(sort_string) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/jsonapionify/api/resource/definitions/sorting.rb', line 69

def sort_fields_from_sort_string(sort_string)
  field_specs = sort_string.to_s.split(',')
  field_specs.each_with_object(SortFieldSet.new) do |field_spec, array|
    field_name, resource = field_spec.split('.').map(&:to_sym).reverse

    # Skip unless this resource
    next unless self <= self.api.resource(resource || type)

    # Assign Sort Fields
    field = SortField.new(field_name)
    field = SortField.new(id_attribute.to_s) if field.id?
    array << field
  end.tap do |field_set|
    field_set << SortField.new(id_attribute.to_s)
  end
end