Rokaki
Rokaki is a small Ruby library that helps you build safe, composable filters for ActiveRecord queries in web requests.
- Works with PostgreSQL, MySQL, SQL Server, Oracle, and SQLite
- Supports simple and nested filters
- LIKE-based matching with prefix/suffix/circumfix modes (circumfix also accepts synonyms: parafix, confix, ambifix)
- Array-of-terms matching (adapter-aware)
- Auto-detects the database backend; specify db only when your app uses multiple adapters or you need an override
Get started below or jump to:
Installation
Add to your application’s Gemfile:
gem "rokaki", "~> 0.18"
Then:
bundle install
Quick start
You can declare mappings in two ways: argument-based (original) or block-form DSL. Both are equivalent.
Argument-based form:
class ArticleQuery
include Rokaki::FilterModel
# Tell Rokaki which model to query. Adapter is auto-detected from the connection.
# If your app uses multiple adapters, pass db: explicitly (e.g., db: :postgres)
filter_model :article
# Map a single query key (:q) to multiple LIKE targets on Article
define_query_key :q
like title: :circumfix, content: :circumfix
# Nested LIKEs on associated models are expressed with hashes
like author: { first_name: :prefix, last_name: :suffix }
attr_accessor :filters
def initialize(filters: {})
@filters = filters
end
end
# In a controller/service:
filtered = ArticleQuery.new(filters: params).results
Block-form DSL (same behavior):
class ArticleQuery
include Rokaki::FilterModel
# Adapter is auto-detected from the connection by default.
# If your app uses multiple adapters, pass db: explicitly (e.g., db: :postgres)
filter_model :article
define_query_key :q
filter_map do
like title: :circumfix, content: :circumfix
nested :author do
like first_name: :prefix, last_name: :suffix
# You can also declare equality filters inside nested contexts
filters :id
end
end
attr_accessor :filters
def initialize(filters: {})
@filters = filters
end
end
# In a controller/service:
filtered = ArticleQuery.new(filters: params).results
Where params can include keys like q, author_first_name, author_last_name, etc. The LIKE mode for each key is defined in your like mapping (e.g., title: :circumfix), and Rokaki builds the appropriate WHERE clauses safely and adapter‑aware.
Matching modes
- prefix: matches values that start with given term(s)
- suffix: matches values that end with given term(s)
- circumfix: matches values that contain given term(s)
All modes accept either a single string or an array of terms.
What’s new in 0.17.0
- Range filters as first-class filters (non-aggregates):
between, lower bounds (from/since/after/start/min), upper bounds (to/until/before/end/max) on top-level and nested fields. - Arrays always mean equality
INlists; use aRangeor{ between: [from, to] }to express ranges. - Block-form DSL parity across
FilterModelandFilterable, with nested declarations for associations and leaves. - Backend auto-detection: adapter inferred from the model connection; pass
db:only for multi-adapter apps or overrides. - Oracle documentation moved under Adapters: see Database adapters → Oracle connections.
Next steps
- Learn the full DSL and examples in Usage
- See adapter specifics (PostgreSQL/MySQL/SQL Server/Oracle/SQLite) in Database adapters
- Configure connections and environment variables in Configuration