Module: Istox::ResultHandler

Defined in:
lib/istox/helpers/result_handler.rb

Class Method Summary collapse

Class Method Details

.filter(query:, meta:) ⇒ Object



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
44
# File 'lib/istox/helpers/result_handler.rb', line 16

def self.filter(query:, meta:)
  return query if meta.blank? || meta.filters.blank?

  meta.filters.each do |filter|
    # chain the query with AND conditions
    # skip if there is no compare present, mean it is for inner filters
    if filter.compare.present?

      validate_filter(filter)
      query = query.where("#{filter.field} #{transform_compare(filter.type, filter.compare)} ?",
                          transform_value(filter.type, filter.value))
    end

    next if filter.filters.blank?

    # contains inner filters, chain the query with AND condition but internally with OR condition
    columns = []
    values = []
    filter.filters.each do |inner_filter|
      validate_filter(filter)
      columns.push("#{inner_filter.field} #{transform_compare(inner_filter.type, inner_filter.compare)} ?")
      values.push(transform_value(inner_filter.type, inner_filter.value))
    end

    query = query.where(columns.join(' OR '), *values) unless columns.empty?
  end

  query
end

.order(query:, meta:) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/istox/helpers/result_handler.rb', line 46

def self.order(query:, meta:)
  return query if meta.blank? || meta.sorts.blank?

  meta.sorts.each do |sort|
    # to prevent sql injection
    # sort.field should contains only alphabet and nothing else
    raise StandardError, 'POSSIBLE_SQL_INJECTION' unless validate_column_name(sort.field)
    # sort.order can only be asc or desc
    raise StandardError, 'POSSIBLE_SQL_INJECTION' unless %w[asc desc].include?(sort.order.downcase)

    query = query.order("#{sort.field.downcase} #{sort.order.upcase}")
  end
  query
end

.paginate(query:, meta:) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/istox/helpers/result_handler.rb', line 61

def self.paginate(query:, meta:)
  current_page = meta.page
  offset = (current_page - 1) * meta.limit
  total = query.count
  data = query.limit(meta.limit).offset(offset)

  page_count = (total + meta.limit - 1) / meta.limit

  OpenStruct.new(
    data: data,
    pagination: {
      page: current_page,
      limit: meta.limit,
      previousPage: current_page - 1,
      currentPage: current_page,
      nextPage: current_page < page_count ? current_page + 1 : 0,
      pageCount: page_count,
      totalCount: total
    }
  )
end

.process(query:, meta:, exclude_filter: false, exclude_order: false, exclude_paginate: false) ⇒ Object

main method to be called, suggested to always use this method and not individual method below



4
5
6
7
8
9
10
11
12
13
14
# File 'lib/istox/helpers/result_handler.rb', line 4

def self.process(query:, meta:, exclude_filter: false, exclude_order: false, exclude_paginate: false)
  query = filter(query: query, meta: meta) unless exclude_filter
  query = order(query: query, meta: meta) unless exclude_order

  # if never set limit, means no pagination is needed
  return OpenStruct.new(data: query.all, pagination: nil) if meta.limit.blank? || meta.limit.zero?

  return paginate(query: query, meta: meta) unless exclude_paginate

  query
end