Module: JSONAPIonify::Api::Resource::Definitions::Pagination::InstanceMethods

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

Instance Method Summary collapse

Instance Method Details

#arel_select_past_cursor(collection, sort_params, key_values) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/jsonapionify/api/resource/definitions/pagination.rb', line 157

def arel_select_past_cursor(collection, sort_params, key_values)
  subquery = sort_params.length.times.map do |i|
    set                             = sort_params[0..i]
    *contains_fields, outside_field = set
    contains_fields.reduce(collection.reorder(nil)) do |relation, field|
      relation.where(
        collection.arel_table[field.name].send(field.contains_arel, key_values[field.name.to_s])
      )
    end.where(
      collection.arel_table[outside_field.name].send(outside_field.outside_arel, key_values[outside_field.name.to_s])
    )
  end.map { |rel| "( #{rel.to_sql} )" }.join(' UNION ')
  collection.from("(#{subquery}) AS #{collection.table_name}").tap(&:first)
rescue ActiveRecord::StatementInvalid
  collection.where(id: collection.find_by_sql(subquery).map(&:id))
end

#array_select_past_cursor(collection, sort_params, key_values) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/jsonapionify/api/resource/definitions/pagination.rb', line 131

def array_select_past_cursor(collection, sort_params, key_values)
  sort_params.length.times.map do |i|
    set                             = sort_params[0..i]
    *contains_fields, outside_field = set

    # Collect the contains results
    contains_results                = contains_fields.map do |field|
      collection.select do |item|
        value          = item.send(field.name)
        expected_value = key_values[field.name]
        value && value.send(field.contains_operator, expected_value)
      end
    end

    # Collect the outside results
    outside_results                 = collection.select do |item|
      value          = item.send(outside_field.name)
      expected_value = key_values[outside_field.name.to_s]
      value && value.send(outside_field.outside_operator, expected_value)
    end

    # Finish the query
    [*contains_results, outside_results].reduce(:&)
  end.reduce(:|) || []
end

#parse_and_validate_cursor(param, cursor, context) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/jsonapionify/api/resource/definitions/pagination.rb', line 174

def parse_and_validate_cursor(param, cursor, context)
  should_error = false
  options      = JSON.parse(Base64.urlsafe_decode64(cursor))

  # Validate Type
  unless options['t'] == self.class.type
    should_error = true
    error(:page_parameter_invalid, :page, param) do
      detail 'The cursor type does not match the resource'
    end
  end

  # Validate Sort
  unless options['s'] == context.params['sort']
    should_error = true
    error(:page_parameter_invalid, :page, param) do
      detail 'The cursor sort does not match the request sort'
    end
  end
  halt if should_error

  options['a']
end