app/resources/maestrano/api/base_resource.rb
module Maestrano
module Api
class BaseResource < JSONAPI::Resource
abstract
include Pundit::Resource
API_SQL_OPERATOR_MAPPING = {
gt: '>',
gte: '>=',
lt: '<',
lte: '<=',
ne: '<>',
like: 'LIKE'
}.freeze
def self.all_filters
# Skipping if there is no tables as calling columns_hash in attribute_type is causing issue
return unless tables_exists?
_attributes.keys.each do |attribute|
type = attribute_type(attribute)
if type == :boolean
# https://github.com/cerebris/jsonapi-resources/issues/852
# make sure filter applied on boolean works
filter(attribute, verify: :verify_boolean_filter)
else
filter(attribute)
end
end
generate_composite_filters
end
def self.generate_composite_filters
_allowed_filters.keys.each do |key|
# iterating through all the api operator and adding them as custom filter
# name.gt, name.like etc...
next unless _model_class
field = "#{_model_class.table_name}.#{key}"
API_SQL_OPERATOR_MAPPING.each do |api_operator, sql_operator|
filter "#{key}.#{api_operator}",
apply: ->(records, value, _options) { records.where("#{field} #{sql_operator} ?", value[0]) }
end
filter "#{key}.none",
apply: ->(records, value, _options) { records.where("#{field} IS NULL") }
filter "#{key}.not",
apply: ->(records, value, _options) { value[0] ? records.where("#{field} <> ?", value[0]) : records.where("#{field} IS NOT NULL") }
filter "#{key}.nin",
apply: ->(records, value, _options) { records.where("#{field} NOT IN (?)", value) }
filter "#{key}.in",
apply: ->(records, value, _options) { records.where("#{field} IN (?)", value) }
end
end
def self.attribute_type(attribute)
_model_class.columns_hash[attribute.to_s]&.type || :string
rescue
:string
end
# If the code is loaded before table are created (during a schema:load for example) this will return false
def self.tables_exists?
@tables_exists = ActiveRecord::Base.connection.table_exists?('users') if @tables_exists.nil?
@tables_exists
end
end
end
end