Module: APIResourceFilterable::HelperMethods

Defined in:
app/api/concerns/api_resource_filterable.rb

Instance Method Summary collapse

Instance Method Details

#filter(resource, filterable_fields: []) ⇒ Object

Filter resources of a collection from the request parameter

Params:

resource

ActiveRecord::Base or ActiveRecord::Relation resource collection to filter data from

filterable_fields

Array of Symbols fields that are allowed to be filtered, default to all


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'app/api/concerns/api_resource_filterable.rb', line 72

def filter(resource, filterable_fields: [])
  # parse the request parameter
  if params[:filter].is_a? Hash
    @filter = params[:filter]
    filterable_fields = filterable_fields.map(&:to_s)

    @filter.each_pair do |field, condition|
      next if filterable_fields.present? && !filterable_fields.include?(field)
      field = resource.connection.quote_string(field)

      next if resource.columns_hash[field].blank?
      field_type = resource.columns_hash[field].type

      # if a function is used
      if func = condition.match(/(?<function>[^\(\)]+)\((?<param>.+)\)/)
        case func[:function]
        when 'not'
          values = func[:param].split(',')
          values.map!(&:to_bool) if field_type == :boolean
          resource = resource.where.not(field => values)
        when 'greater_then'
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" > ?", func[:param])
        when 'less_then'
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" < ?", func[:param])
        when 'greater_then_or_equal'
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" >= ?", func[:param])
        when 'less_then_or_equal'
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" <= ?", func[:param])
        when 'between'
          param = func[:param].split(',')
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" BETWEEN ? AND ?", param.first, param.last)
        when 'like'
          resource = resource.where("\"#{resource.table_name}\".\"#{field}\" LIKE ?", func[:param])
        end      # if not function

      else
        values = condition.split(',')
        values.map!(&:to_bool) if field_type == :boolean
        resource = resource.where(field => values)
      end
    end
  end

  return resource
end