Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ibm-skills-network/sn_filterable
A fully featured filtering gem designed for Ruby on Rails apps with Postgres databases
https://github.com/ibm-skills-network/sn_filterable
filter filtering postgres rails
Last synced: about 2 months ago
JSON representation
A fully featured filtering gem designed for Ruby on Rails apps with Postgres databases
- Host: GitHub
- URL: https://github.com/ibm-skills-network/sn_filterable
- Owner: ibm-skills-network
- License: mit
- Created: 2022-12-05T17:00:49.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-29T16:17:29.000Z (3 months ago)
- Last Synced: 2024-11-15T05:20:50.146Z (2 months ago)
- Topics: filter, filtering, postgres, rails
- Language: Ruby
- Homepage:
- Size: 313 KB
- Stars: 5
- Watchers: 11
- Forks: 1
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
# SnFilterable
Welcome to the Skills Network Filterable gem!
This gem provides a method for developers to quickly implement a customizable search and filter for their data with live-reloading.
Live examples of the gem's use can be viewed at [Skills Network's Author Workbench](https://author.skills.network), primarily under the [organizations tab](https://author.skills.network/organizations)
![](sn_filterable_demo.gif)
## Requirements
There are a couple key requirements for your app to be compatible with this gem:
1. You need to have [AlpineJS](https://alpinejs.dev/essentials/installation) loaded into the page where you plan to use SnFilterable
2. Your app needs to be running [TailwindCSS](https://tailwindcss.com/docs/guides/ruby-on-rails)## Installation
Add this line to your application's Gemfile:
```ruby
gem "sn_filterable"
```And then execute:
```bash
bundle install
```##### Make the following adjustments to your codebase
1. Add the necessary translations and customize as desired
```yaml
# en.yml
en:
# Other translations
shared:
filterable:
view_filter_button: "View filters"
results_per_page: "Results per page"
clear_all: "Clear all"
pagination:
previous_page: "Previous"
next_page: "Next"
```2. Require the necessary JavaScript (dependent on AlpineJS being included with your App)
```javascript
// application.js converted to application.js.erb// other imports
<%= SnFilterable.load_js %>
```If your application does not allow for use of `.js.erb` files the JavaScript can be loaded by adding the following to your layout:
```javascript
<%= javascript_tag nonce: true do %>
<%= SnFilterable.load_js.html_safe %>
<% end %>
```3. Configure your app's Tailwind to scan the gem
```javascript
// tailwind.config.js
const execSync = require('child_process').execSync;
const output = execSync('bundle show sn_filterable', { encoding: 'utf-8' });module.exports = {
// other config settings
content: [
// other content
output.trim() + '/app/**/*.{erb,rb}'
]
// other config settings
};
```## Usage
#### The MainComponent: Search Bar and sidebar
The MainComponent is what is demo'd in the introduction. It consists of the search bar and a sidebar for filters.
If you only wish to use the Search bar an optional `show_sidebar: false` parameter can be passed to `SnFilterable::MainComponent` in the view.
There are three components which work to provide the text search functionality:
1. Filters in the given model:
```ruby
# model.rb
class Model < ApplicationRecord
include SnFilterable::FilterableFILTER_SCOPE_MAPPINGS = {
"search_name": :filter_by_name
# 'search_name' will be referenced from the view
}.freezeSORT_SCOPE_MAPPINGS = {
"sort_name": :sort_by_name
# 'sort_name' will be referenced from the controller
}.freezescope :filter_by_name, ->(search) { where(SnFilterable::WhereHelper.contains("name", search)) }
scope :sort_by_name, -> { order :name }
# 'name' is a string column defined on the Model# Model code...
end
```2. Setting up the controller
* While `:default_sort` is an optional parameter it is recommended
```ruby
# models_controller.rb
@search = Model.filter(params:, default_sort: ["sort_name", :asc].freeze)
@models = @search.items
```3. Rendering the ViewComponent
```html
<%= render SnFilterable::MainComponent.new(frame_id: "some_unique_id", filtered: @search, filters: [], search_filter_name: "search_name") do %>
<% @models.each do |model| %>
<%= model.name %>
<% end %>
<%= filtered_paginate @search %> # Kaminari Gem Pagination
<% end %>
```#### The MainComponent: Adding filters to the sidebar
Adding filters to the sidebar requires changes to two files though we recommend storing the data across three files and will demsontrate as such.
1. Add filters to Model
```ruby
# app/models/model.rb
class Model < ApplicationRecord
# inclusion statement from introductionFILTER_SCOPE_MAPPINGS = {
# other filter scopes...
"model_type_filter": :filter_by_type
}.freeze
# 'model_type_filter' will be referenced in step 2ARRAY_FILTER_SCOPES = %i[model_type_filter].freeze
# safelist of all filters we will be rendering in our sidebar
scope :filter_by_type, ->(model_type_input) { where(model_type: model_type_input) }
# where 'model_type' is an attribute defined on Model
end
```2. Create filter options
```ruby
# app/models/filter.rb
# We store in a filter.rb model, but you can store as desired
class Filter
MODEL_FILTERS = [
{
multi: true,
title: "Type",
filter_name: "model_type_filter",
filters: %w(Special Normal).map { |type| { name: type, value: type } }
# Allows us to filter between 'Special' and 'Normal' model types
# Note we recommend storing the %w(Special Normal) array at a central location for easier validation and manipulation
}
].freeze
end
```3. Render as part of our MainComponent
```html<%= render SnFilterable::MainComponent.new(frame_id: "some_unique_id", filtered: @search, filters: Filter::MODEL_FILTERS, search_filter_name: "search_name") do %>
<% end %>
```## Testing / Development
This gem using [RSpec](https://rspec.info) for testing. Tests can be running locally by first setting up the dummy database/app as follows:
```bash
docker compose up -d
cd spec/dummy
rails db:create
rails db:schema:load
```Now the test suite can be run from the project root using
```bash
bundle exec rspec
```### Using a Development Version
Your changes can be tested manually by making one of the following additions to an App's Gemfile:
For using a local version:
```ruby
gem "sn_filterable", path: "path/to/gem/sn_filterable"
```For using a GitHub branch:
```ruby
gem "sn_filterable", git: "https://github.com/ibm-skills-network/sn_filterable.git", branch: "defaults_to_main"
```## Contributing
Once you have made your updates to the codebase do the following to ensure a smooth merge:
1. Update `lib/sn_filterable/version.rb` to follow [Semantic Versioning](https://semver.org)
2. Run `bundle` to update the `Gemfile.lock` with your new version
Bug reports and pull requests are welcome on [GitHub](https://github.com/ibm-skills-network/sn_filterable).
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).