ransack 3.2.1 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/codeql.yml +72 -0
- data/.github/workflows/cronjob.yml +6 -9
- data/.github/workflows/deploy.yml +1 -1
- data/.github/workflows/rubocop.yml +2 -2
- data/.github/workflows/test-deploy.yml +1 -1
- data/.github/workflows/test.yml +23 -22
- data/.rubocop.yml +7 -1
- data/CHANGELOG.md +86 -0
- data/CONTRIBUTING.md +40 -21
- data/Gemfile +10 -10
- data/README.md +4 -9
- data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +1 -1
- data/bug_report_templates/test-ransacker-arel-present-predicate.rb +5 -1
- data/docs/docs/getting-started/advanced-mode.md +1 -1
- data/docs/docs/getting-started/search-matches.md +1 -1
- data/docs/docs/getting-started/simple-mode.md +6 -2
- data/docs/docs/getting-started/sorting.md +45 -53
- data/docs/docs/going-further/acts-as-taggable-on.md +4 -4
- data/docs/docs/going-further/form-customisation.md +1 -1
- data/docs/docs/going-further/i18n.md +3 -3
- data/docs/docs/going-further/other-notes.md +2 -2
- data/docs/docs/going-further/polymorphic-search.md +6 -0
- data/docs/docs/going-further/saving-queries.md +1 -1
- data/docs/docs/going-further/searching-postgres.md +1 -1
- data/docs/package.json +7 -3
- data/docs/yarn.lock +2371 -1928
- data/lib/polyamorous/{activerecord_6.1_ruby_2 → activerecord}/join_dependency.rb +14 -4
- data/lib/polyamorous/polyamorous.rb +3 -4
- data/lib/ransack/adapters/active_record/base.rb +78 -7
- data/lib/ransack/adapters/active_record/context.rb +2 -1
- data/lib/ransack/configuration.rb +25 -12
- data/lib/ransack/constants.rb +125 -0
- data/lib/ransack/context.rb +34 -5
- data/lib/ransack/helpers/form_builder.rb +3 -3
- data/lib/ransack/helpers/form_helper.rb +3 -2
- data/lib/ransack/nodes/attribute.rb +2 -2
- data/lib/ransack/nodes/condition.rb +80 -7
- data/lib/ransack/nodes/grouping.rb +3 -3
- data/lib/ransack/nodes/node.rb +1 -1
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/predicate.rb +1 -1
- data/lib/ransack/ransacker.rb +1 -1
- data/lib/ransack/search.rb +9 -4
- data/lib/ransack/translate.rb +2 -2
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +38 -2
- data/lib/ransack.rb +3 -6
- data/ransack.gemspec +1 -1
- data/spec/ransack/adapters/active_record/base_spec.rb +89 -0
- data/spec/ransack/configuration_spec.rb +9 -9
- data/spec/ransack/helpers/form_builder_spec.rb +8 -8
- data/spec/ransack/helpers/form_helper_spec.rb +36 -2
- data/spec/ransack/nodes/condition_spec.rb +24 -0
- data/spec/ransack/predicate_spec.rb +36 -1
- data/spec/ransack/translate_spec.rb +1 -1
- data/spec/support/schema.rb +55 -10
- metadata +9 -22
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb +0 -1
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb +0 -1
- data/lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb +0 -1
- data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +0 -1
- data/lib/polyamorous.rb +0 -1
- data/lib/ransack/adapters/active_record/ransack/constants.rb +0 -128
- data/lib/ransack/adapters/active_record/ransack/context.rb +0 -56
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +0 -61
- data/lib/ransack/adapters/active_record/ransack/translate.rb +0 -8
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +0 -47
- data/lib/ransack/adapters.rb +0 -64
- data/lib/ransack/nodes.rb +0 -8
- /data/lib/polyamorous/{activerecord_6.1_ruby_2 → activerecord}/join_association.rb +0 -0
- /data/lib/polyamorous/{activerecord_6.1_ruby_2 → activerecord}/reflection.rb +0 -0
- /data/lib/ransack/{adapters/active_record.rb → active_record.rb} +0 -0
@@ -27,6 +27,10 @@ def index
|
|
27
27
|
end
|
28
28
|
```
|
29
29
|
|
30
|
+
:::caution
|
31
|
+
By default, searching and sorting are authorized on any column of your model. See [Authorization (allowlisting/denylisting)](/going-further/other-notes.md#authorization-allowlistingdenylisting) on how to prevent this.
|
32
|
+
:::
|
33
|
+
|
30
34
|
### Default search options
|
31
35
|
|
32
36
|
#### Search parameter
|
@@ -50,7 +54,7 @@ This may be disabled by setting the `strip_whitespace` option in a Ransack initi
|
|
50
54
|
|
51
55
|
```ruby
|
52
56
|
Ransack.configure do |c|
|
53
|
-
# Change whitespace stripping
|
57
|
+
# Change whitespace stripping behavior.
|
54
58
|
# Default is true
|
55
59
|
c.strip_whitespace = false
|
56
60
|
end
|
@@ -60,7 +64,7 @@ end
|
|
60
64
|
|
61
65
|
The two primary Ransack view helpers are `search_form_for` and `sort_link`,
|
62
66
|
which are defined in
|
63
|
-
[Ransack::Helpers::FormHelper](https://github.com/activerecord-hackery/ransack/lib/ransack/helpers/form_helper.rb).
|
67
|
+
[Ransack::Helpers::FormHelper](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/helpers/form_helper.rb).
|
64
68
|
|
65
69
|
### Form helper
|
66
70
|
|
@@ -10,70 +10,62 @@ title: Sorting
|
|
10
10
|
You can add a form to capture sorting and filtering options together.
|
11
11
|
|
12
12
|
```erb
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
<
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
<div class="form-group">
|
39
|
-
<%= f.label :readability_gteq, t('Readability') %> >=
|
40
|
-
<%= f.search_field :readability_gteq %>
|
41
|
-
</div>
|
42
|
-
|
43
|
-
<div class="form-group">
|
44
|
-
<i><%= @articles.total_count %> articles</i>
|
45
|
-
</div>
|
46
|
-
|
47
|
-
<div class="form-group">
|
48
|
-
<hr/>
|
49
|
-
<div class="filters-header-content">
|
50
|
-
<%= link_to request.path, class: 'form-link' do %>
|
51
|
-
<i class="far fa-undo icon-l"></i><%= t('Clear_all') %>
|
52
|
-
<% end %>
|
53
|
-
|
54
|
-
<%= f.submit t('Filter'), class: 'btn btn-primary' %>
|
55
|
-
</div>
|
56
|
-
</div>
|
13
|
+
# app/views/posts/index.html.erb
|
14
|
+
|
15
|
+
<%= search_form_for @q do |f| %>
|
16
|
+
<%= f.label :title_cont %>
|
17
|
+
<%= f.search_field :title_cont %>
|
18
|
+
|
19
|
+
<%= f.submit "Search" %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<table>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th><%= sort_link(@q, :title, "Title") %></th>
|
26
|
+
<th><%= sort_link(@q, :category, "Category") %></th>
|
27
|
+
<th><%= sort_link(@q, :created_at, "Created at") %></th>
|
28
|
+
</tr>
|
29
|
+
</thead>
|
30
|
+
|
31
|
+
<tbody>
|
32
|
+
<% @posts.each do |post| %>
|
33
|
+
<tr>
|
34
|
+
<td><%= post.title %></td>
|
35
|
+
<td><%= post.category %></td>
|
36
|
+
<td><%= post.created_at.to_s(:long) %></td>
|
37
|
+
</tr>
|
57
38
|
<% end %>
|
58
|
-
</
|
59
|
-
</
|
39
|
+
</tbody>
|
40
|
+
</table>
|
60
41
|
```
|
61
42
|
|
62
|
-
|
63
43
|
## Sorting in the Controller
|
64
44
|
|
65
45
|
To specify a default search sort field + order in the controller `index`:
|
66
46
|
|
67
47
|
```ruby
|
68
|
-
|
69
|
-
|
70
|
-
|
48
|
+
# app/controllers/posts_controller.rb
|
49
|
+
class PostsController < ActionController::Base
|
50
|
+
def index
|
51
|
+
@q = Post.ransack(params[:q])
|
52
|
+
@q.sorts = 'title asc' if @q.sorts.empty?
|
53
|
+
|
54
|
+
@posts = @q.result(distinct: true)
|
55
|
+
end
|
56
|
+
end
|
71
57
|
```
|
72
58
|
|
73
59
|
Multiple sorts can be set by:
|
74
60
|
|
75
61
|
```ruby
|
76
|
-
|
77
|
-
|
78
|
-
|
62
|
+
# app/controllers/posts_controller.rb
|
63
|
+
class PostsController < ActionController::Base
|
64
|
+
def index
|
65
|
+
@q = Post.ransack(params[:q])
|
66
|
+
@q.sorts = ['title asc', 'created_at desc'] if @q.sorts.empty?
|
67
|
+
|
68
|
+
@posts = @q.result(distinct: true)
|
69
|
+
end
|
70
|
+
end
|
79
71
|
```
|
@@ -67,24 +67,24 @@ When you're writing a `Ransack` search form, you can choose any of the following
|
|
67
67
|
|
68
68
|
### Option A - Match keys exactly
|
69
69
|
|
70
|
-
Option `
|
70
|
+
Option `A` will match keys exactly. This is the solution to choose if you want to distinguish 'Home' from 'Homework': searching for 'Home' will return just the `Task` with id 1. It also allows searching for more than one tag at once (comma separated):
|
71
71
|
- `Home, Personal` will return task 1
|
72
72
|
- `Home, Homework` will return task 1 and 2
|
73
73
|
|
74
74
|
### Option B - match key combinations
|
75
75
|
|
76
|
-
Option `
|
76
|
+
Option `B` will match all keys exactly. This is the solution if you wanna search for specific combinations of tags:
|
77
77
|
- `Home` will return nothing, as there is no Task with just the `Home` tag
|
78
78
|
- `Home, Personal` will return task 1
|
79
79
|
|
80
80
|
### Option C - match substrings
|
81
81
|
|
82
|
-
Option `
|
82
|
+
Option `C` is used to match substrings. This is useful when you don't care for the exact tag, but only for part of it:
|
83
83
|
- `Home` will return task 1 and 2 (`/Home/` matches both `"Home"` and `"Homework"`)
|
84
84
|
|
85
85
|
### Option D - select from a list of tags
|
86
86
|
|
87
|
-
In Option D we allow the user to select a list of valid tags and then search
|
87
|
+
In Option `D` we allow the user to select a list of valid tags and then search against them. We use the plural name here.
|
88
88
|
|
89
89
|
```erb
|
90
90
|
<div class='form-group'>
|
@@ -3,7 +3,7 @@ sidebar_position: 4
|
|
3
3
|
title: Form customisation
|
4
4
|
---
|
5
5
|
|
6
|
-
Predicate and attribute labels in forms may be specified with I18n in a translation file (see the locale files in [Ransack::Locale](https://github.com/activerecord-hackery/ransack/
|
6
|
+
Predicate and attribute labels in forms may be specified with I18n in a translation file (see the locale files in [Ransack::Locale](https://github.com/activerecord-hackery/ransack/tree/main/lib/ransack/locale) for more examples):
|
7
7
|
|
8
8
|
```yml
|
9
9
|
# locales/en.yml
|
@@ -6,12 +6,12 @@ title: i18n
|
|
6
6
|
# i18n and Ransack
|
7
7
|
|
8
8
|
Ransack translation files are available in
|
9
|
-
[Ransack::Locale](https://github.com/activerecord-hackery/ransack/lib/ransack/locale). You may also be interested in one of the
|
9
|
+
[Ransack::Locale](https://github.com/activerecord-hackery/ransack/tree/main/lib/ransack/locale). You may also be interested in one of the
|
10
10
|
many translations for Ransack available at
|
11
11
|
http://www.localeapp.com/projects/2999.
|
12
12
|
|
13
13
|
Predicate and attribute translations in forms may be specified as follows (see
|
14
|
-
the translation files in [Ransack::Locale](https://github.com/activerecord-hackery/ransack/lib/ransack/locale) for more examples):
|
14
|
+
the translation files in [Ransack::Locale](https://github.com/activerecord-hackery/ransack/tree/main/lib/ransack/locale) for more examples):
|
15
15
|
|
16
16
|
locales/en.yml:
|
17
17
|
```yml
|
@@ -27,7 +27,7 @@ en:
|
|
27
27
|
gt: greater than
|
28
28
|
lt: less than
|
29
29
|
models:
|
30
|
-
person:
|
30
|
+
person: Passenger
|
31
31
|
attributes:
|
32
32
|
person:
|
33
33
|
name: Full Name
|
@@ -182,7 +182,7 @@ for an `auth_object` key in the options hash which can be used by your own
|
|
182
182
|
overridden methods.
|
183
183
|
|
184
184
|
Here is an example that puts all this together, adapted from
|
185
|
-
[this blog post by Ernie Miller](
|
185
|
+
[this blog post by Ernie Miller](https://ernie.io/2012/05/11/why-your-ruby-class-macros-might-suck-mine-did/).
|
186
186
|
In an `Article` model, add the following `ransackable_attributes` class method
|
187
187
|
(preferably private):
|
188
188
|
|
@@ -354,7 +354,7 @@ argument are not easily usable yet, because the array currently needs to be
|
|
354
354
|
wrapped in an array to function (see
|
355
355
|
[this issue](https://github.com/activerecord-hackery/ransack/issues/404)),
|
356
356
|
which is not compatible with Ransack form helpers. For this use case, it may be
|
357
|
-
better for now to use [ransackers](https://
|
357
|
+
better for now to use [ransackers](https://activerecord-hackery.github.io/ransack/going-further/ransackers) instead,
|
358
358
|
where feasible. Pull requests with solutions and tests are welcome!
|
359
359
|
|
360
360
|
### Grouping queries by OR instead of AND
|
@@ -38,3 +38,9 @@ Location.ransack(locatable_of_House_type_number_eq: 100).result
|
|
38
38
|
```
|
39
39
|
|
40
40
|
note the `_of_House_type_` added to the search key. This allows Ransack to correctly specify the table names in SQL join queries.
|
41
|
+
|
42
|
+
For namespaced models you should use a quoted string containing the standard Ruby module notation
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Location.ransack('locatable_of_Residences::House_type_number_eq' => 100).result
|
46
|
+
```
|
@@ -72,7 +72,7 @@ class ApplicationController < ActionController::Base
|
|
72
72
|
end
|
73
73
|
|
74
74
|
protected
|
75
|
-
# GENERATE A GENERIC SESSION KEY BASED ON
|
75
|
+
# GENERATE A GENERIC SESSION KEY BASED ON THE CONTROLLER NAME
|
76
76
|
def search_key
|
77
77
|
"#{controller_name}_search".to_sym
|
78
78
|
end
|
@@ -13,7 +13,7 @@ See [this issue](https://github.com/activerecord-hackery/ransack/issues/321) for
|
|
13
13
|
|
14
14
|
### Using a fixed key
|
15
15
|
|
16
|
-
See here for searching on a fixed key in a JSONB column: https://
|
16
|
+
See here for searching on a fixed key in a JSONB column: https://activerecord-hackery.github.io/ransack/going-further/ransackers/#postgres-columns
|
17
17
|
|
18
18
|
### Using the JSONB contains operator
|
19
19
|
|
data/docs/package.json
CHANGED
@@ -14,15 +14,19 @@
|
|
14
14
|
"write-heading-ids": "docusaurus write-heading-ids"
|
15
15
|
},
|
16
16
|
"dependencies": {
|
17
|
-
"@docusaurus/core": "^2.
|
18
|
-
"@docusaurus/preset-classic": "^2.
|
19
|
-
"@easyops-cn/docusaurus-search-local": "^0.
|
17
|
+
"@docusaurus/core": "^2.2.0",
|
18
|
+
"@docusaurus/preset-classic": "^2.2.0",
|
19
|
+
"@easyops-cn/docusaurus-search-local": "^0.33.5",
|
20
20
|
"@mdx-js/react": "^1.6.22",
|
21
21
|
"clsx": "^1.1.1",
|
22
22
|
"prism-react-renderer": "^1.3.1",
|
23
23
|
"react": "^17.0.2",
|
24
24
|
"react-dom": "^17.0.2"
|
25
25
|
},
|
26
|
+
"resolutions": {
|
27
|
+
"trim": "^0.0.3",
|
28
|
+
"got": "^11.8.5"
|
29
|
+
},
|
26
30
|
"browserslist": {
|
27
31
|
"production": [
|
28
32
|
">0.5%",
|