FilterMe

Build Status Code Climate Gem Version

A Rails/ActiveRecord filtering gem

FilterMe provids helpers and classes that makes request filtering easy using Ruby classes and object oriented development.

Installation

gem "filter_me", "0.1.0"

Filter:

* Highly subject to change as the API moves closer to 1.0

class AccountsFilter < FilterMe::ActiveRecordFilter
  model Account
  association :user

  field :cost, :all
  field :account_type, [:matches] # Symbols are Arel::Predications methods
end

class AccountsController < ApplicationController
  include FilterMe

  def index
    @accounts = filter_me(Account.all)
    respond_to do |format|
      format.json { render json: @accounts }
    end
  end
end

Plain request: http://0.0.0.0:3000/accounts.json

{"accounts":[
  {"id":1, "cost":100000, "account_type":"admin"},
  {"id":2, "cost":50000, "account_type":"paid"},
  {"id":3, "cost":10000, "account_type":"free"}
]}

Performs:

SELECT "accounts".* FROM "accounts"

Now with some filtering: http://0.0.0.0:3000/accounts.json?filters%5Baccount_type%5D%5Bmatches%5D=paid

{"accounts":[
  {"id":2, "cost":50000, "account_type":"paid"}
]}

Performs:

SELECT "accounts".* FROM "accounts" WHERE ("accounts"."account_type" LIKE 'paid')

Nested Filtering:

class UsersFilter < FilterMe::ActiveRecordFilter
  model User
  association :account

  field :username, [:matches, :eq, :not_eq] # Symbols are Arel::Predications methods
  field :email, [:matches, :eq, :not_eq] # Symbols are Arel::Predications methods
end

class UsersController < ApplicationController
  include FilterMe

  def index
    @users = filter_me(User.all)
    respond_to do |format|
      format.json { render json: @users }
    end
  end
end

Plain request: http://0.0.0.0:3000/users.json

{"users":[
  {"id":1, "username":"test1", "email":"[email protected]", "account": {
    "id":1, "cost":100000, "account_type":"admin"
  }},
  {"id":2, "username":"test2", "email":"[email protected]", "account":{
    "id":2, "cost":50000, "account_type":"paid"
  }},
  {"id":3, "username":"test3", "email":"[email protected]", "account":{
    "id":3, "cost":10000, "account_type":"free"
  }}
]}
Performs:
``` SQL
SELECT "users".* FROM "users"

Now with some filtering: http://0.0.0.0:3000/users.json?filters%5Baccount%5D%5Bcost%5D%5Blt%5D=50000

{"users":[
  {"id":3, "username":"test3", "email":"[email protected]", "account":{
    "id":3,"cost":10000, "account_type":"free"
  }}
]}

Performs:

SELECT "users".* FROM "users" INNER JOIN "accounts" ON "accounts"."user_id" = "users"."id"
    WHERE ("accounts"."cost" < 50000)

Need to provide some top secret super duper special filtering? Go ahead:

class UsersFilter < FilterMe::ActiveRecordFilter
  model User

  def special_filter(relation, filters)
    relation.where(id: filters)
  end
end

http://0.0.0.0:3000/users.json?filters%5Baccount%5D%5Bcost%5D%5Bgteq%5D=50000&filters%5Bspecial_filter%5D%5B%5D=3&filters%5Bspecial_filter%5D%5B%5D=2 Now performs:

SELECT "users".* FROM "users" INNER JOIN "accounts" ON "accounts"."user_id" = "users"."id"
    WHERE ("accounts"."cost" >= 50000) AND "users"."id" IN (3, 2)

License

Copyright (c) 2014, Filter Me is developed and maintained by Sam Clopton, and is released under the open MIT Licence.