Filterable is a micro gem that allows you to build filterable collections in a modular fashion. You can encapsulate filtering logic inside filter objects and attach them to collections.
For example, if you have a TimeOfDay
filter, a geospatial Location
filter, or an elastic search FullText
filter, you can hide the horrific implementation inside a filter object.
Keeps your models from growing out of control and taking on too much responsibility Rule #4 Extract Query Objects
Instead of chaining a bunch of scopes for your API response, you can instantiate a Filterable collection, pass in the get params, and present it back.
Add this line to your application's Gemfile:
gem 'filterable', github: 'coderly/filterable'
And then execute:
$ bundle
Imagine you have an ActiveRecord model called User with an id, username, tags, and timestamps.
class User
acts_as_taggable
end
You could create a user collection and make use of these filters like so:
class UserCollection < Filterable::Collection
filter :registered_after, CreatedAfterFilter
filter :category, TagFilter
end
You could define the filters as so
class TimeFilter
def initialize(time)
@time = time
end
def call(collection)
if @time
condition = collection.arel_table[:created_at].gt(@time)
collection.where(condition)
else
collection
end
end
end
class TagFilter
def initialize(category)
@category = category
end
def call(collection)
if @category
collection.tagged_with @category
else
collection
end
end
end
When you then call
UserCollection.new(User.all, created_after: yesterday, category: 'moderator')
You get a collection of filtered users.