" string
# to isolate session persistence of multiple filterrific instances.
# Override this to share session persisted filter params between
# multiple filterrific instances. Set to `false` to disable session
# persistence.
# * default_filter_params: optional, to override model defaults
# * available_filters: optional, to further restrict which filters are
# in this filterrific instance.
# * sanitize_params: optional, defaults to `true`. If true, all filterrific
# params will be sanitized to prevent reflected XSS attacks.
# This method also persists the params in the session and handles resetting
# the filterrific params.
# In order for reset_filterrific to work, it's important that you add the
# `or return` bit after the call to `initialize_filterrific`. Otherwise the
# redirect will not work.
@filterrific = initialize_filterrific(
Student,
params[:filterrific],
select_options: {
sorted_by: Student.options_for_sorted_by,
with_country_id: Country.options_for_select,
},
persistence_id: "shared_key",
default_filter_params: {},
available_filters: [:sorted_by, :with_country_id],
sanitize_params: true,
) || return
# Get an ActiveRecord::Relation for all students that match the filter settings.
# You can paginate with will_paginate or kaminari.
# NOTE: filterrific_find returns an ActiveRecord Relation that can be
# chained with other scopes to further narrow down the scope of the list,
# e.g., to apply permissions or to hard coded exclude certain types of records.
@students = @filterrific.find.page(params[:page])
# Respond to html for initial page load and to js for AJAX filter updates.
respond_to do |format|
format.html
format.js
end
# Recover from invalid param sets, e.g., when a filter refers to the
# database id of a record that doesn’t exist any more.
# In this case we reset filterrific and discard all filter params.
rescue ActiveRecord::RecordNotFound => e
# There is an issue with the persisted param_set. Reset it.
puts "Had to reset filterrific params: #{e.message}"
redirect_to(reset_filterrific_url(format: :html)) && return
end
...
end
```
--------------------------------
### Sorting Students by Created At
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Sorts students based on their creation timestamp. Includes the table name to prevent ambiguity when joining tables.
```ruby
direction = /desc$/.match?(sort_option) ? "desc" : "asc"
case sort_option.to_s
when /^created_at_/
order("students.created_at #{direction}")
when /^name_/
order("LOWER(students.last_name) #{direction}, LOWER(students.first_name) #{direction}")
when /^country_name_/
order("LOWER(countries.name) #{direction}").includes(:country).references(:country)
else
raise(ArgumentError, "Invalid sort option: #{sort_option.inspect}")
end
```
--------------------------------
### Basic Search Scope with LIKE Operator
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Implement a basic search functionality using SQL's LIKE operator. This scope is case-insensitive with MySQL but case-sensitive with PostgreSQL; downcasing is used for cross-database compatibility.
```ruby
scope :search_query, ->(query) {
# Searches the students table on the 'first_name' and 'last_name' columns.
# Matches using LIKE, automatically appends '%' to each term.
# LIKE is case INsensitive with MySQL, however it is case
# sensitive with PostGreSQL. To make it work in both worlds,
# we downcase everything.
return nil if query.blank?
# condition query, parse into individual keywords
terms = query.downcase.split(/\s+/
# replace "*" with "%" for wildcard searches,
# append '%', remove duplicate '%'s
terms = terms.map { |e|
(e.tr("*", "%" ) + "%" ).gsub(/%+/,"%" )
}
# configure number of OR conditions for provision
# of interpolation arguments. Adjust this if you
# change the number of OR conditions.
num_or_conds = 2
where(
terms.map { |_term|
"(LOWER(students.first_name) LIKE ? OR LOWER(students.last_name) LIKE ?)"
}.join(" AND "),
*terms.map { |e| [e] * num_or_conds }.flatten,
)
}
```
--------------------------------
### Use Filterrific in Controller Index Action
Source: http://filterrific.clearcove.ca/
Initialize Filterrific in your controller's index action to handle filtering and pagination. Respond to HTML and JS formats.
```ruby
def index
@filterrific = initialize_filterrific(
Student,
params[:filterrific]
) or return
@students = @filterrific.find.page(params[:page])
respond_to do |format|
format.html
format.js
end
end
```
--------------------------------
### Filter Students by All Given Roles (Ruby)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Use this scope to find students who possess ALL of the specified roles. It constructs a complex SQL query using AREL to avoid duplicate records and potential issues with DISTINCT clauses.
```ruby
scope :with_all_role_ids, ->(role_ids) {
# get a reference to the join table
role_assignments = RoleAssignment.arel_table
# get a reference to the filtered table
students = Student.arel_table
# let AREL generate a complex SQL query
role_ids.map(&:to_i).inject(self) { |rel, role_id|
rel.where(
RoleAssignment
.where(role_assignments[:student_id].eq(students[:id]))
.where(role_assignments[:role_id].eq(role_id))
.exists,
)
}
}
```
--------------------------------
### Provide Select Options for Filterrific
Source: http://filterrific.clearcove.ca/pages/active_record_model_api.html
Define a presenter method on a related model to provide options for a Filterrific select input. This method should return an array of arrays, where each inner array contains the display text and the corresponding value.
```ruby
def self.options_for_select
order("LOWER(name)").map { |e| [e.name, e.id] }
end
```
--------------------------------
### Include Filterrific jQuery Observers and Spinner
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
Add this line to your `application.js` file to include the necessary jQuery behaviors for Filterrific form observers and the AJAX spinner, assuming you are using the asset pipeline.
```javascript
//= require filterrific/filterrific-jquery
```
--------------------------------
### Filter by Date Range - Less Than (Ruby)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Scope to filter records by a date column, excluding the specified reference time. Use this for the upper boundary of a semi-open interval.
```ruby
# always exclude the upper boundary for semi open intervals
scope :created_at_lt, ->(reference_time) {
where("students.created_at < ?", reference_time)
}
```
--------------------------------
### Student Model Definition
Source: http://filterrific.clearcove.ca/pages/example_application.html
Defines the Student model, including its attributes and its association with the Country model. This is the primary model used for filtering in the demo application.
```ruby
# app/models/student.rb
class Student < ActiveRecord::Base
# db columns:
# integer: id
# string: first_name
# string: last_name
# text: email
# integer: country_id
# datetime: created_at
belongs_to :country
end
```
--------------------------------
### Apply Filterrific to ActiveRecord Model
Source: http://filterrific.clearcove.ca/pages/active_record_model_api.html
Apply the `filterrific` directive to your model to enable filtering. Define default filter parameters and list all available filters. This acts as a security measure, similar to `strong_params` for filter settings.
```ruby
class Student < ActiveRecord::Base
# db columns:
# integer: id
# string: first_name
# string: last_name
# text: email
# integer: country_id
# datetime: created_at
# This directive enables Filterrific for the Student class.
# We define a default sorting by most recent sign up, and then
# we make a number of filters available through Filterrific.
filterrific(
default_filter_params: { sorted_by: "created_at_desc" },
available_filters: [
:sorted_by,
:search_query,
:with_country_id,
:with_created_at_gte,
],
)
# ActiveRecord association declarations
belongs_to :country
# Scope definitions. We implement all Filterrific filters through ActiveRecord
# scopes. In this example we omit the implementation of the scopes for brevity.
# Please see 'Scope patterns' for scope implementation details.
scope :search_query, ->(query) {
# Filters students whose name or email matches the query
...
}
scope :sorted_by, ->(sort_key) {
# Sorts students by sort_key
...
}
scope :with_country_id, ->(country_ids) {
# Filters students with any of the given country_ids
...
}
scope :with_created_at_gte, ->(ref_date) {
...
}
# This method provides select options for the `sorted_by` filter select input.
# It is called in the controller as part of `initialize_filterrific`.
def self.options_for_sorted_by
[
["Name (a-z)", "name_asc"],
["Registration date (newest first)", "created_at_desc"],
["Registration date (oldest first)", "created_at_asc"],
["Country (a-z)", "country_name_asc"],
]
end
end
```
--------------------------------
### Filter Students with Comments
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Finds students who have at least one associated comment. Uses a SQL EXISTS subquery.
```ruby
scope :with_comments, -> {
where(
"EXISTS (SELECT 1 from comments WHERE students.id = comments.student_id)",
)
}
```
--------------------------------
### Filter Students Without Comments
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Finds students who have never posted a comment. Uses a SQL NOT EXISTS subquery.
```ruby
scope :without_comments, -> {
where(
%(NOT EXISTS (
SELECT 1 FROM comments WHERE comments.student_id = students.id
)),
)
}
```
--------------------------------
### Filter Students Without Given Roles (Ruby)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
This scope finds students who DO NOT have any of the specified roles. It is similar to the `with_all_role_ids` scope but uses the `.not` operator to invert the existence check.
```ruby
scope :without_role_ids, ->(role_ids) {
role_assignments = RoleAssignment.arel_table
students = Student.arel_table
where(
RoleAssignment
.where(role_assignments[:student_id].eq(students[:id]))
.where(role_assignments[:role_id].in([*role_ids].map(&:to_i)))
.exists
.not,
)
}
```
--------------------------------
### Country Model Definition
Source: http://filterrific.clearcove.ca/pages/example_application.html
Defines the Country model, which represents countries and has a one-to-many association with the Student model. Some students may not be associated with a country.
```ruby
# app/models/country.rb
class Country < ActiveRecord::Base
# db columns:
# integer: id
# string: name
has_many :students
end
```
--------------------------------
### Filter by Date Range - Greater Than or Equal (Ruby)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Scope to filter records by a date column, including the specified reference time. Use this for the lower boundary of a semi-open interval.
```ruby
# always include the lower boundary for semi open intervals
scope :created_at_gte, ->(reference_time) {
where("students.created_at >= ?", reference_time)
}
```
--------------------------------
### Filter Students with Comments Since a Specific Time
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Finds students who have posted a comment after a given reference time. Uses a SQL EXISTS subquery with a date condition.
```ruby
scope :with_comments_since, ->(reference_time) {
where([
%(
EXISTS (
SELECT 1
FROM comments
WHERE students.id = comments.student_id
AND comments.created_at >= ?)
),
reference_time,
])
}
```
--------------------------------
### Filter by Associated Table Column (Hash Syntax)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Use this scope to filter records based on a column in an associated table using hash syntax. It requires joining the associated table.
```ruby
scope :with_country_name, ->(country_name) {
where(country: { name: country_name }).joins(:country)
}
```
--------------------------------
### Rendering Filtered Results Partial in Rails
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
This partial renders the list of records. It's designed to be updated via AJAX. Use `page_entries_info` for pagination information and `will_paginate` for pagination controls.
```erb
<%# app/views/students/_list.html.erb %> <%= page_entries_info students # provided by will_paginate %>
| Name | Email | Country | Registered at |
<% students.each do |student| %> | <%= link_to(student.full_name, student_path(student)) %> | <%= student.email %> | <%= student.country_name %> | <%= student.decorated_created_at %> |
<% end %>
<%= will_paginate students # provided by will_paginate %>
```
--------------------------------
### Filter Students with Any Role IDs
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Finds students who have any of the specified role IDs. This scope traverses a has_many :through association.
```ruby
scope :with_any_role_ids, ->(role_ids) {
```
--------------------------------
### Sorting Scope Convention
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Define a scope for sorting records. The suggested naming convention is `sorted_by` to avoid potential collisions with ActiveRecord reserved names.
```ruby
scope :sorted_by, ->(sort_option) {
```
--------------------------------
### Filterrific Sorted By Scope
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
Define a `sorted_by` scope in your model to handle sorting logic. This scope determines how column headers are capitalized and maps them to the correct database order clause.
```ruby
scope :sorted_by, ->(sort_option) {
direction = /desc$/.match?(sort_option) ? "desc" : "asc"
case sort_option.to_s
when /^name/
order("LOWER(students.name) #{direction}")
when /^email/
order("LOWER(students.email) #{direction}")
when /^country/
order("LOWER(students.country) #{direction}")
when /^registered_at/
order("LOWER(students.decorated_created_at) #{direction}")
else
raise(ArgumentError, "Invalid sort option: #{sort_option.inspect}")
end
}
```
--------------------------------
### Filter by Associated Table Column (Sanitized SQL)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Use this scope for more complex filtering needs, such as 'greater than' comparisons, by employing sanitized SQL snippets. It also requires joining the associated table.
```ruby
scope :with_country_name, ->(country_name) {
where("countries.name = ?", country_name).joins(:country)
}
```
--------------------------------
### Filterrific Form Helper in Rails View
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
Use `form_for_filterrific` in your Rails view to create a form for filter settings. It automatically handles AJAX submission, spinners, and input name prefixes. Add the `filterrific-periodically-observed` class to text fields for live updates.
```erb
<%# app/views/students/index.html.erb %>Students
<%# Filterrific adds the `form_for_filterrific` view helper: * adds dom id 'filterrific_filter' * applies javascript behaviors: * AJAX form submission on change * AJAX spinner while AJAX request is being processed * sets form_for options like :url, :method and input name prefix %> <%= form_for_filterrific @filterrific do |f| %> Search <%# give the search field the 'filterrific-periodically-observed' class for live updates %> <%= f.text_field( :search_query, class: 'filterrific-periodically-observed' ) %>
Country <%= f.select( :with_country_id, @filterrific.select_options[:with_country_id], { include_blank: '- Any -' } ) %>
Registered after <%= f.text_field(:with_created_at_gte, class: 'js-datepicker') %>
Sorted by <%= f.select(:sorted_by, @filterrific.select_options[:sorted_by]) %>
<%= link_to( 'Reset filters', reset_filterrific_url, ) %>
<%# add an automated spinner to your form when the list is refreshed %> <%= render_filterrific_spinner %> <% end %><%= render( partial: 'students/list', locals: { students: @students }) %>
```
--------------------------------
### Updating Filtered List via AJAX in Rails
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
This ERB template is used for JavaScript responses to update the student list. It renders the `_list.html.erb` partial and replaces the content of the `#filterrific_results` div.
```erb
<%# app/views/students/index.js.erb %><% js = escape_javascript( render(partial: 'students/list', locals: { students: @students })) $("#filterrific_results").html("<%= js %>");
```
--------------------------------
### Filterrific Sorting Link Helper
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
Use `filterrific_sorting_link` in your view's table headers to create sortable links. This method toggles sort direction for attributes defined in the `sorted_by` scope.
```erb
<%# app/views/students/_list.html.erb %>
<%= page_entries_info students # provided by will_paginate %>
| <%= filterrific_sorting_link(@filterrific, :name) %> |
<%= filterrific_sorting_link(@filterrific, :email) %> |
<%= filterrific_sorting_link(@filterrific, :country) %> |
<%= filterrific_sorting_link(@filterrific, :registered_at) %> |
<% students.each do |student| %>
| <%= link_to(student.full_name, student_path(student)) %> |
<%= student.email %> |
<%= student.country_name %> |
<%= student.decorated_created_at %> |
<% end %>
<%= will_paginate students # provided by will_paginate %>
```
--------------------------------
### Add Filterrific to ActiveRecord Model
Source: http://filterrific.clearcove.ca/
Integrate Filterrific into your ActiveRecord model by calling the filterrific method and defining available filters.
```ruby
filterrific(
default_filter_params: { sorted_by: 'created_at_desc' },
available_filters:
:sorted_by,
:search_query,
:with_country_id,
:with_created_at_gte
)
# define ActiveRecord scopes for
# :search_query, :sorted_by, :with_country_id, and :with_created_at_gte
```
--------------------------------
### Scope Definition for Multiple Form Inputs (Ruby)
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Defines a scope that accepts a hash of attributes, typically from multiple form inputs combined using `fields_for`. The `distance_attrs` hash is expected to contain keys like `:max_distance` and `:city`.
```ruby
scope :with_distance, ->(distance_attrs) {
# `distance_attrs` is a hash with two keys:
# {
# :max_distance => '10',
# :city => 'Vancouver',
# }
where(...)
}
```
--------------------------------
### Filter by Column Values with ActiveRecord Scopes
Source: http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html
Define scopes to filter records based on specific column values or foreign keys. The `[*column_ids]` expression ensures that single values are also handled as arrays.
```ruby
scope :with_country_id, ->(country_ids) {
where(country_id: [*country_ids])
}
# filters on 'gender' attribute
scope :with_gender, ->(genders) {
where(gender: [*genders])
}
```
--------------------------------
### Disable AJAX Auto Submits with Filterrific Form
Source: http://filterrific.clearcove.ca/pages/action_view_api.html
Override the default form ID to disable automatic AJAX form submissions. Add `remote: true` if you still want AJAX, and include a submit button. Ensure no inputs have the `.filterrific-periodically-observed` class.
```erb
<%= form_for_filterrific @filterrific, html: { id: 'filterrific-no-ajax-auto-submit' } do |f| %>
...
<%= f.submit 'Filter' %>
<% end %>
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.