-
Notifications
You must be signed in to change notification settings - Fork 76
Customizing Filters
In this document we will be using 3 models: User, Event and EventUser so we can demonstrate some amazing filtering capabilities of the gem. Here are the table definitions of the models.
Users Table
create_table :users do |t| t.string :first_name t.string :last_name t.date :birthday t.string :sex t.timestamps end
Events Table
create_table :events do |t| t.integer :creator_id t.string :type t.string :name t.string :headline t.datetime :start_time t.datetime :end_time t.timestamps end add_index :events, [:creator_id]
Event Users Table
create_table :event_users do |t| t.integer :event_id t.integer :user_id t.timestamps end add_index :event_users, [:event_id] add_index :event_users, [:user_id] add_index :event_users, [:event_id, :user_id]
Here are the actual model objects with their associations:
User Model
class User < ActiveRecord::Base has_many :events has_many :events_users end
Event Model
class Event < ActiveRecord::Base belongs_to :user, :class_name => 'User', :foreign_key => :creator_id has_many :event_users end
EventUser Model
class EventUser < ActiveRecord::Base belongs_to :event belongs_to :user end
We will also use a samples_controller with an index action. The controller code looks like this:
class SamplesController < ApplicationController def index # All examples assume you are placing the code in here end end
The index.html.erb will simply look like this:
<%= will_filter_tag(@users)%>
In some cases we will use @users in other cases @events or @event_users
Creating a basic filter is just a matter of adding the following lines of code to your controller:
class OrdersController < ApplicationController def index @users = User.filter(:params => params) end end
And adding a filter display tags to your page: (index.html.erb)
<%= will_filter_tag(@users) %>
If you would like to display the will_filter table, you can add the following tag right below the filter tag: (index.html.erb)
<%= will_filter_table_tag(@orders) %>
Note: Since we are not going to be looking at the table tag here, assume it is always present on the page.
This will create the following filter on the page:
Filter with conditions will look like:
What is a filter? Well, filter is simply a collection of conditions and some additional attributes, like pagination, sorting, etc…
A filter condition is comprised of 3 elements: model attribute key, operator and container. Operators and containers options are dynamically discovered based on the column data type.
If you look at the config/will_filter/config.yml you will see that operators and containers can be easily added or modified based on the application needs.
Here is what the config looks like:
containers: # container implementation mapping nil: WillFilter::Containers::Nil numeric: WillFilter::Containers::Numeric numeric_range: WillFilter::Containers::NumericRange numeric_delimited: WillFilter::Containers::NumericDelimited double: WillFilter::Containers::Double double_range: WillFilter::Containers::DoubleRange double_delimited: WillFilter::Containers::DoubleDelimited date_time_range: WillFilter::Containers::DateTimeRange single_date: WillFilter::Containers::SingleDate date: WillFilter::Containers::Date date_time: WillFilter::Containers::DateTime date_range: WillFilter::Containers::DateRange text: WillFilter::Containers::Text text_delimited: WillFilter::Containers::TextDelimited boolean: WillFilter::Containers::Boolean list: WillFilter::Containers::List filter_list: WillFilter::Containers::FilterList data_types: # mapping between data types and containers bigint: [nil, numeric, numeric_range, numeric_delimited] numeric: [nil, numeric, numeric_range, numeric_delimited] smallint: [nil, numeric, numeric_range, numeric_delimited] integer: [nil, numeric, numeric_range, numeric_delimited] int: [nil, numeric, numeric_range, numeric_delimited] float: [nil, double, double_range, double_delimited] double: [nil, double, double_range, double_delimited] timestamp: [nil, date_time, date_time_range, single_date] datetime: [nil, date_time, date_time_range, single_date] date: [nil, date, date_range] char: [nil, text, text_delimited] character: [nil, text, text_delimited] varchar: [nil, text, text_delimited] text: [nil, text, text_delimited] text[]: [nil, text, text_delimited] bytea: [nil, text, text_delimited] boolean: [nil, boolean] tinyint: [nil, boolean] operators: # operators precedence is: 100 is_not: 200 is_on: 300 is_in: 400 is_provided: 500 is_not_provided: 600 is_after: 700 is_before: 800 is_in_the_range: 900 contains: 1000 does_not_contain: 1100 starts_with: 1200 ends_with: 1300 is_greater_than: 1400 is_less_than: 1500 is_filtered_by: 1600
The data_types section maps each data type to an array of available containers, while each container provides information on which operators it supports.
The entire framework is very customizable so you can add custom containers, operators and data types.