0.0
No commit activity in last 3 years
No release in over 3 years
A very basic gem for generating JSON responses for collections.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
>= 0

Runtime

 Project Readme

Filternator

A very basic gem for generating JSON responses for collections.

Currently supported:

  • Pagination (via will_paginate)
  • Simple Filters

Not supported:

  • Combining multiple filters
  • Filters with parameters

We use this gem in production, but it's uses are very specific to what we use. YMMV.

Installation

Add this line to your application's Gemfile:

gem 'filternator'

And then execute:

$ bundle

Or install it yourself as:

$ gem install filternator

Usage

Given a model:

class User < ActiveRecord::Base

  def self.all_filters
    %w(all paying beta_users)
  end

  def self.paying
    where(paying: true)
  end

  def self.beta_users
    where(beta: true)
  end

  def self.visible
    where(visible: true)
  end

end

Then you can create a filter in the controller:

def index
  render json: filter.apply(params)
end

private

def filter
  Filternator.new(scope: User.visible)
end

And you can execute it, like this:

get :index, filter: "all", "page" => 2
expect(response.body).to eq({
  users: [
    {
      id:     31,
      email:  "jennifer@example.org"
      # etc...
    }
  ],
  meta: {
    filters: ["all", "paying", "beta_users"],
    applied_filter: "all",
    pagination: {
      total:        31,
      total_pages:  2,
      first_page:   false,
      last_page:    true,
      # and some more
    }
  }
}.to_json)

Pagination

You can pass the pagination options directly into will_paginate's view helper.

<%= will_paginate OpenStruct.new(@user_response.body["meta"]["pagination"]) %>

(you should probably clean this up, but you get the point)

Stats

You can also generate an overview of the counts of each filter.

# in your controller
def stats
  render json: filter.stats
end

Then the output looks something like this:

get :stats
expect(response.body).to eq({
  all:         31,
  paying:      4,
  beta_users:  13,
}.to_json)

Configuration

There are a bunch of ways to configure the filter.

Presenters

Use a presenter to change the output of the collection, by giving something that can be mapped on each item.

UserDecorator = Struct.new(:user) do

  def self.to_proc
    method(:new).to_proc
  end

  def as_json(*)
    { name: user.name, email: user.email }
  end

end

filter = Filternator.new(scope: User, presenter: UserDecorator)

Scope name

By default, the name of the results is the plural of the model's name. You can change it by providing the :scope_name option.

filter = Filternator.new(scope: User.admins, scope_name: "administrators")

All filters

In the example mentioned above, I defined the list of available methods on the class. You can also change the available filters per filterer, by supplying the :all_filters option.

# prohibits the access to the `paying`-scope.
filter  = Filternator.new(scope: User, all_filters: %w(all beta_users))

Default filter

Note for ActiveRecord 3: all will not return a scope, but an array and will not work. You use .scoped instead. You can also override .all to return .scoped, but that might break some of your code. If you choose a different name than all, you need to specify it, and allow it with all_filters.

filter = Filternator.new(scope: User, default_filter: "scoped", all_filters: %w(scoped other))

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request