module Fetcha::ClassMethods

Public Instance Methods

fetch(params = {}) click to toggle source
# File lib/fetcha.rb, line 8
def fetch(params = {})
  results = all
  query_scope = params['scope']
  filters = params['filter']
  sorting = params['sort']
  pages = params['page']
  search = params['search']
  results = process_scope(results, query_scope) if query_scope
  results = process_filtering(results, filters) if filters
  results = process_sorting(results, sorting) if sorting
  results = process_pagination!(results, pages) if pages
  results = process_search(results, search) if search
  results.extending(PaginationTotalCount)
end

Private Instance Methods

contains_filter(datasource, field, value) click to toggle source
# File lib/fetcha.rb, line 152
def contains_filter(datasource, field, value)
  datasource.where("#{field} ilike ?", "%#{value}%")
end
ends_with_filter(datasource, field, value) click to toggle source
# File lib/fetcha.rb, line 160
def ends_with_filter(datasource, field, value)
  datasource.where("#{field} ilike ?", "%#{value}")
end
fetchable_opts() click to toggle source
# File lib/fetcha.rb, line 46
def fetchable_opts
  @fetchable_opts ||=
    {
      filtering: {},
      sorting: {},
      scopes: Set.new,
      pagination: {
        default_size: 10,
        max_size: 50
      }
    }
end
filterable_on(*fields) click to toggle source
# File lib/fetcha.rb, line 64
def filterable_on(*fields)
  fields.each do |field|
    fetchable_opts[:filtering][field.to_s] = nil
  end
end
fulltext_search_on(*fields) click to toggle source
# File lib/fetcha.rb, line 59
def fulltext_search_on(*fields)
  include PgSearch
  pg_search_scope :search_full_text, against: fields, using: { trigram: { threshold: 0.1 }, tsearch: { prefix: true } }
end
method_missing(name, *args, block) click to toggle source
Calls superclass method
# File lib/fetcha.rb, line 164
def method_missing(name, *args, block)
  raise ForbiddenError if name =~ /.*_filter$/
  super
end
paginatable(args = {}) click to toggle source
# File lib/fetcha.rb, line 78
def paginatable(args = {})
  fetchable_opts[:pagination].keys.each do |k|
    next unless args.keys.include? k
    fetchable_opts[:pagination][k] = args[k]
  end
end
presence_filter(datasource, field, value) click to toggle source
# File lib/fetcha.rb, line 144
def presence_filter(datasource, field, value)
  if value
    datasource.where.not(field => nil)
  else
    datasource.where(field => nil)
  end
end
process_filtering(datasource, filters = {}) click to toggle source
# File lib/fetcha.rb, line 93
def process_filtering(datasource, filters = {})
  filter_opts = fetchable_opts[:filtering]
  includes = Set.new

  real_filters = filters.select do |k|
    next unless filter_opts.keys.include? k
    values = k.split('.')
    includes << values.first if values.second.present?
    true
  end
  results = includes.empty? ? datasource : datasource.includes(includes.to_a)

  real_filters.each do |key, value|
    v = if value =~ /,/
          value.split(',')
        else
          value
        end
    results = process_operation(results, key, v)
  end
  results
end
process_operation(datasource, field, value) click to toggle source
# File lib/fetcha.rb, line 122
def process_operation(datasource, field, value)
  results = datasource
  if value.is_a? Hash
    value.each do |operation, value|
      results = send("#{operation}_filter", results, field, value)
    end
  else
    results = results.where(field => value)
  end
  results
end
process_pagination!(datasource, page = {}) click to toggle source
# File lib/fetcha.rb, line 134
def process_pagination!(datasource, page = {})
  page_opts = fetchable_opts[:pagination]
  max_size = page_opts[:max_size]
  size = (page['size'] || page_opts[:default_size]).to_i
  number = (page['number'] || '1').to_i - 1
  raise ForbiddenError if size > max_size || size < 1 || number < 0
  offset = number * size
  datasource = datasource.offset(offset).limit(size)
end
process_scope(datasource, query_scope) click to toggle source
# File lib/fetcha.rb, line 85
def process_scope(datasource, query_scope)
  datasource.send(query_scope) if fetchable_opts[:scopes].include? query_scope.to_sym
end
process_sorting(datasource, sorting) click to toggle source
# File lib/fetcha.rb, line 116
def process_sorting(datasource, sorting)
  sort_params = SortParams.sorted_fields(sorting, fetchable_opts[:sorting])
  datasource = datasource.order(sort_params) if sort_params
  datasource
end
scopable_with(*fields) click to toggle source
# File lib/fetcha.rb, line 74
def scopable_with(*fields)
  fetchable_opts[:scopes] = Set.new(fields.map(&:to_s))
end
sortable_on(*fields) click to toggle source
# File lib/fetcha.rb, line 70
def sortable_on(*fields)
  fetchable_opts[:sorting] = Set.new(fields.map(&:to_s))
end
starts_with_filter(datasource, field, value) click to toggle source
# File lib/fetcha.rb, line 156
def starts_with_filter(datasource, field, value)
  datasource.where("#{field} ilike ?", "#{value}%")
end