Module: Boosted::Controllers::Filterable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/boosted/controllers/filterable.rb
Overview
Provides functionality for filtering records from an ActiveRecord::Relation
in a controller.
Example usage:
class UsersController < ApplicationController
include Filterable
filterable_by :name, :created_at, 'accounts.kind'
def index
scope = filter(User.joins(:account))
render json: scope
end
end
Example requests:
GET /users?name=John
GET /users?created_at=2020-01-01
GET /users?accounts.kind=premium
GET /users?accounts.kind=premium&accounts.kind.rel=not_eq
Filters can be combined:
GET /users?name=John&created_at=2020-01-01
Renaming filter keys:
In some cases, you may not want to expose the actual column names to the client. In such cases, you can rename the filter keys by passing a hash to the filterable_by
method.
Example:
class UsersController < ApplicationController
include Filterable
filterable_by :name, :created_at, 'accounts.kind' => 'kind'
def index
scope = filter(User.joins(:account))
render json: scope
end
end
Example requests:
GET /users?kind=premium
Using relations:
In some cases, you may want to filter records based on a relation. For example, you may want to filter users based on operands like:
-
greater than
-
less than
-
not equal
To see the full list of operands, check the Boosted::Queries::Filter::RELATIONS
constant.
To use the operands, you must pass a parameter appended with ‘.rel`, and the value of a valid operand.
Example requests:
GET /users?created_at=2020-01-01&created_at.rel=>
GET /users?created_at=2020-01-01&created_at.rel=<
GET /users?created_at=2020-01-01&created_at.rel=not_eq
When the operand relation requires multiple values, like in
, not_in
, or between
, you can pass an array of values.
Example requests:
GET /users?created_at[]=2020-01-01&created_at[]=2020-01-03&created_at.rel=in
GET /users?created_at[]=2020-01-01&created_at[]=2020-01-03&created_at.rel=between
Instance Method Summary collapse
- #filter(scope, filter_conditions: filter_conditions(*filter_fields, *mapped_filter_fields)) ⇒ ActiveRecord::Relation
- #filter_conditions(*fields) ⇒ Array<Hash>
Instance Method Details
#filter(scope, filter_conditions: filter_conditions(*filter_fields, *mapped_filter_fields)) ⇒ ActiveRecord::Relation
100 101 102 |
# File 'lib/boosted/controllers/filterable.rb', line 100 def filter(scope, filter_conditions: filter_conditions(*filter_fields, *mapped_filter_fields)) Boosted::Queries::Filter.call(scope, filter_conditions:) end |
#filter_conditions(*fields) ⇒ Array<Hash>
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/boosted/controllers/filterable.rb', line 106 def filter_conditions(*fields) fields.filter_map do |filter_opt| field = filter_name(filter_opt) next if filter_value(filter_opt).blank? && %w[is_null is_not_null].exclude?(filter_rel_value(filter_opt)) { field:, value: filter_value(filter_opt), relation: filter_rel_value(filter_opt).presence || (filter_value(filter_opt).is_a?(Array) ? "in" : "=") } end end |