lib/json_api/support/concerns/regular_filters.rb
# frozen_string_literal: true module JSONAPI module Support module RegularFilters def apply_regular_filters(scope) return scope if filter_params.empty? regular_filters = filter_params.reject { |k, _v| k.to_s.include?(".") } return scope if regular_filters.empty? regular_filters.reduce(scope) do |current_scope, (filter_name, filter_value)| apply_regular_filter(current_scope, filter_name.to_s, filter_value) end end private def apply_regular_filter(scope, filter_name, filter_value) return scope if empty_filter_value?(filter_value) column_filter = parse_column_filter(filter_name) if column_filter apply_column_filter(scope, column_filter, filter_value) else apply_scope_fallback(scope, filter_name, filter_value) end end def apply_column_filter(scope, column_filter, raw_value) condition = build_column_condition(column_filter, raw_value) condition ? apply_condition(scope, condition) : scope rescue StandardError => e log_filter_error(column_filter, column_filter[:operator], e) scope end def build_column_condition(column_filter, raw_value) column = model_class.column_for_attribute(column_filter[:column]) return nil unless column value = normalize_filter_value_for_model(model_class, column, raw_value) return nil if value.nil? build_condition(model_class, column, value, column_filter[:operator]) end def log_filter_error(column_filter, operator, error) return unless defined?(Rails.logger) Rails.logger.warn("Filter error for #{column_filter[:column]}_#{operator}: #{error.class} - #{error.message}") end def apply_scope_fallback(scope, filter_name, filter_value) return scope unless model_class.respond_to?(filter_name.to_sym) scope.public_send(filter_name.to_sym, filter_value) rescue ArgumentError, NoMethodError scope end end end end