Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .circleci/config.yml

This file was deleted.

15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
## Unreleased

- Add support for `...` date ranges within `jsonb` filters, applied as a `BETWEEN` clause per key
- Fix `jsonb` values containing `...` being parsed as a top-level `Range` instead of a hash, which raised `NoMethodError` for nested params and produced an invalid `Range` for JSON object strings (issue #80)
## 1.1.0

- Add support for Rails 7.1, 7.2, and 8.0 (#67)
- Migrate CI from Travis to GitHub Actions; test matrix covers Ruby 2.7–3.3 against Rails 7.0–8.0 (#67)
- Add `allow_nil: true` option to `filter_on` to enable `IS NULL` filtering for non-JSONB column types (#84)
- Add support for date range filtering on JSONB keys, using the same `...` range format as other filters (#83)
- Fix boolean filter being silently skipped when the value is `false` (#58). Note: filters with empty-string values are now applied (previously skipped); review consumers if you relied on the old behavior.
- Fix `NameError` in JSONB filtering when value is an Array (#56)
- Reorganize documentation into a `docs/` directory (#68)

### Breaking changes:
- Drop support for Rails 6.1 / ActiveRecord 6.1
- Require `activerecord >= 7.0`

## 1.0.0

Expand Down
37 changes: 37 additions & 0 deletions docs/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,29 @@ end

The lambda receives the validator object, which gives you access to the filter value and allows you to add errors using `validator.errors.add(:field_name, "error message")`.

## Filtering on Null Values

By default, non-JSONB filters cannot match rows where a column is `NULL`. Setting `allow_nil: true` on a filter lets consumers opt in to `IS NULL` filtering by passing the string `null` as the filter value.

```ruby
class PostsController < ApplicationController
include Sift

filter_on :assignee_id, type: :int, allow_nil: true
end
```

With `allow_nil: true`:

- `?filters[assignee_id]=null` produces `WHERE assignee_id IS NULL`
- `?filters[assignee_id][]=null&filters[assignee_id][]=5` combines the null check with the other values, producing `WHERE assignee_id IS NULL OR assignee_id IN (5)`

The `null` value is case-insensitive, so `null` and `NULL` behave identically.

Filters without `allow_nil: true` are unaffected: `null` is treated as an ordinary value and validated against the filter's type (for example, an `int` filter returns a `400` validation error).

> JSONB columns already support null filtering without this option — see [Filter on JSONB Column](#filter-on-jsonb-column).

## Filter on JSONB Column

Usually JSONB columns stores values as an Array or an Object (key-value), in both cases the parameter needs to be sent in a JSON format.
Expand Down Expand Up @@ -199,6 +222,20 @@ Will return records with next values stored in the JSONB column `metadata`:
{ data_1: {another: 'information'} } # When the JSONB key "data_2" is not set.
```

### Filtering JSONB Keys on Date Ranges

JSONB key values support date ranges using the same `...` separator as other [range filters](#filter-on-ranges). Pass a range string as the value for a key:

- `?filters[metadata]={"published_at":"2018-01-01...2018-01-02"}`

This extracts the key and produces a `BETWEEN` condition:

```sql
metadata->>'published_at' BETWEEN '2018-01-01' AND '2018-01-02'
```

The bounds are parsed as dates when possible and fall back to the raw string otherwise, matching the behavior of the top-level `datetime` range filter.

## Filter on JSON Array

`int` type filters support sending the values as an array in the URL Query parameters. For example `?filters[id]=[1,2]`. This is a way to keep payloads smaller for GET requests. When URI encoded this will become `filters%5Bid%5D=%5B1,2%5D` which is much smaller the standard format of `filters%5Bid%5D%5B%5D=1&&filters%5Bid%5D%5B%5D=2`.
Expand Down
2 changes: 1 addition & 1 deletion lib/sift/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Sift
VERSION = "1.0.1".freeze
VERSION = "1.1.0".freeze
end