class ActiveHashRelation::FilterApplier

Attributes

configuration[R]

Public Class Methods

new(resource, params, include_associations: false, model: nil, is_not: false) click to toggle source
# File lib/active_hash_relation/filter_applier.rb, line 12
def initialize(resource, params, include_associations: false, model: nil, is_not: false)
  @configuration = Module.nesting.last.configuration
  @resource = resource
  if params.respond_to?(:to_unsafe_h)
    @params = HashWithIndifferentAccess.new(params.to_unsafe_h)
  else
    @params = HashWithIndifferentAccess.new(params)
  end
  @include_associations = include_associations
  @model = find_model(model)
  is_not ? @is_not = true : @is_not = false
end

Public Instance Methods

apply_filters() click to toggle source
# File lib/active_hash_relation/filter_applier.rb, line 25
def apply_filters
  run_or_filters
  run_not_filters

  table_name = @model.table_name
  @model.columns.each do |c|
    next if @params[c.name.to_s].nil?
    next if @params[c.name.to_s].is_a?(String) && @params[c.name.to_s].blank?

    case c.type
    when :integer
      if @model.defined_enums[c.name] && @model.defined_enums[c.name][@params[c.name]]
        @params[c.name] = @model.defined_enums[c.name][@params[c.name]]
      end
      @resource = filter_integer(@resource, c.name, table_name, @params[c.name])
    when :float
      @resource = filter_float(@resource, c.name, table_name, @params[c.name])
    when :decimal
      @resource = filter_decimal(@resource, c.name, table_name, @params[c.name])
    when :string, :uuid, :text
      @resource = filter_string(@resource, c.name, table_name, @params[c.name])
    when :date
      @resource = filter_date(@resource, c.name, table_name, @params[c.name])
    when :datetime, :timestamp
      @resource = filter_datetime(@resource, c.name, table_name, @params[c.name])
    when :boolean
      @resource = filter_boolean(@resource, c.name, table_name, @params[c.name])
    end
  end

  if @params.include?(:scopes)
    if ActiveHashRelation.configuration.filter_active_record_scopes
      @resource = filter_scopes(@resource, @params[:scopes], @model)
    else
      Rails.logger.warn('Ignoring ActiveRecord scope filters because they are not enabled')
    end
  end
  @resource = filter_associations(@resource, @params, @model) if @include_associations
  @resource = apply_limit(@resource, @params[:limit]) if @params.include?(:limit)
  @resource = apply_sort(@resource, @params[:sort], @model) if @params.include?(:sort)

  return @resource
end
filter_class(resource_name) click to toggle source
# File lib/active_hash_relation/filter_applier.rb, line 69
def filter_class(resource_name)
  "#{configuration.filter_class_prefix}#{resource_name.pluralize}#{configuration.filter_class_suffix}".constantize
end
run_not_filters() click to toggle source
# File lib/active_hash_relation/filter_applier.rb, line 92
def run_not_filters
  if @params[:not].is_a?(Hash) && !@params[:not].blank?
    @resource = self.class.new(
      @resource,
      @params[:not],
      include_associations: @include_associations,
      is_not: true
    ).apply_filters
  end
end
run_or_filters() click to toggle source
# File lib/active_hash_relation/filter_applier.rb, line 73
def run_or_filters
  if @params[:or].is_a?(Array)
    if ActiveRecord::VERSION::MAJOR < 5
      return Rails.logger.warn("OR query is supported on ActiveRecord 5+")
    end

    if @params[:or].length >= 2
      array = @params[:or].map do |or_param|
        self.class.new(@resource, or_param, include_associations: @include_associations).apply_filters
      end

      @resource = @resource.merge(array[0])
      array[1..-1].each{|query| @resource = @resource.or(query)}
    else
      Rails.logger.warn("Can't run an OR with 1 element!")
    end
  end
end