Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/westonganger/search_architect
Dead simple, powerful and fully customizable searching for your Rails or ActiveRecord models and associations.
https://github.com/westonganger/search_architect
activerecord activerecord-models rails rails-search ruby search search-scope sql
Last synced: about 1 month ago
JSON representation
Dead simple, powerful and fully customizable searching for your Rails or ActiveRecord models and associations.
- Host: GitHub
- URL: https://github.com/westonganger/search_architect
- Owner: westonganger
- License: mit
- Created: 2020-12-30T01:02:56.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2023-10-31T23:53:37.000Z (about 1 year ago)
- Last Synced: 2024-10-04T19:18:22.860Z (about 2 months ago)
- Topics: activerecord, activerecord-models, rails, rails-search, ruby, search, search-scope, sql
- Language: Ruby
- Homepage:
- Size: 87.9 KB
- Stars: 6
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Search Architect
Dead simple, powerful and fully customizable searching for your Rails or ActiveRecord models and associations. Capable of searching any attribute type using SQL type casting.
Why This Library:
If you are considering using the `ransack` gem, then you should think again because `ransack` is a very dirty solution that completely integrates the Searching, Sorting, and Views as requirements of eachother. Not having these features separated hurts your ability to customize and modify your code. Don't fall into this trap. This gem is just one concern with one scope. If you want to customize it later you can simply copy the code directly into your project.
# Installation
```ruby
gem 'search_architect'
```Then add `include SearchArchitect` to your ApplicationRecord or models.
# Defining Search Scopes
You can define any search scopes on your model using the following:
```ruby
class Comment < ApplicationRecord
include SearchArchitect
has_many :comments
endclass Comment < ApplicationRecord
include SearchArchitect
belongs_to :user
belongs_to :post
endclass Post < ApplicationRecord
include SearchArchitect
has_many :commentssearch_scope :search, attributes: [
:title,
:content,
:number, ### non-string fields are automatically converted to a searchable type using sql CAST method
"CAST((#{self.table_name}.number+100) AS CHAR)", ### Plain SQL fully supported
:created_at, ### automatically converts date/time fields to searchable string type using sql CAST method, uses default db output format by defaultcomments: [
:number,
:content,user: [
"users.name",comments: [
{table_alias: "users_comments"}, ### Must manually specify a table_alias when we have multiple associations referencing the same table
"users_comments.content",
],
]
],
]
search_scope :search_with_locale, sql_variables: [:locale], attributes: [
"#{self.table_name}.name_translations ->> :locale", # specify any variables as symbols, Ex. :locale
]
search_scope :search_custom_date_format, attributes: [
# PostgreSQL, Oracle
"TO_CHAR(#{self.table_name}.approved_at, 'YYYY-mm-dd')",
# MySQL
"DATE_FORMAT(#{self.table_name}.approved_at, '%Y-%m-%d')",
# SQLite
"strftime(#{self.table_name}.approved_at, '%Y-%m-%d')",
]end
```You would now have access to the following searching methods:
```ruby
posts = Post.search(params[:search])posts = Post.search_with_locale(params[:search], sql_variables: {locale: @current_locale})
```# Search Types
We includes two different searching types:
### Full String Search
Considers entire string as one search. In my experience this is the natural choice however the multi-search proves to be very powerful.
```ruby
posts = Post.search(params[:search], search_type: :full_search)
### OR
posts = Post.search(params[:search]) # defaults to :full_search
```### Multi Word Full-text Search
Recommended. Split words on whitespace characters, Quoting is allowed to combine words
The following type of queries are supported:
- `foo` (rows must include foo)
- `foo bar` (rows must include both foo and bar)
- `"foo bar"` (rows must include the phrase "foo bar")```ruby
posts = Post.search(params[:search], search_type: :multi_search)
```# Comparison Operators
Different comparison operators can be specified by adding the `:comparison_operator` argument
```ruby
posts = Post.search(params[:search], comparison_operator: '=')
```The default is `ILIKE` if Postgresql or `LIKE` if non-postgres. Current valid options are: `ILIKE`, `LIKE`, and `=`
# SQL Type Casting Cheatsheet
- Most Types:
- `CAST(posts.number AS CHAR)`
- `CAST(posts.created_at AS CHAR)` - uses default db output format by default
- Custom Date/Time Formatting:
- Postgresql, Oracle
- `TO_CHAR(posts.created_at, 'YYYY-mm-dd')`
- MySQL
- `DATE_FORMAT(posts.created_at, '%Y-%m-%d')`
- SQLite
`strftime(posts.created_at, '%Y-%m-%d')`#### Limitation: Boolean columns
Boolean columns are only searched by their true/false value. Searching boolean fields by the column name is not possible because apparently SQL has the restriction where you cannot use `CASE` statements within `WHERE` clauses.
For example if you were trying to search a `boolean` by the string of its column name:
`CASE WHEN users.admin IS TRUE THEN 'admin' ELSE '' END`
You will find it extremely difficult to work around this. Instead I strongly recommend handling your booleans filtering logic seperately from your search logic.
# Search Form / Views
We do not provide built in view templates because this is a major restriction to applications. If your looking for starter template feel free to use the following example:
- [examples/_search_form.html.slim](./examples/_search_form.html.slim)
# Key Models Provided & Additional Customizations
A key aspect of this library is its simplicity and small API. For major functionality customizations we encourage you to first delete this gem and then copy this gems code directly into your repository.
I strongly encourage you to read the code for this library to understand how it works within your project so that you are capable of customizing the functionality later.
- [lib/search_architect/concerns/search_scope_concern.rb](./lib/search_architect/concerns/search_scope_concern.rb)
# Credits
Created & Maintained by [Weston Ganger](https://westonganger.com) - [@westonganger](https://github.com/westonganger)