ransack 2.6.0 → 3.0.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.nojekyll +0 -0
  3. data/CHANGELOG.md +75 -13
  4. data/README.md +45 -1039
  5. data/docs/.gitignore +20 -0
  6. data/docs/.nojekyll +0 -0
  7. data/docs/babel.config.js +3 -0
  8. data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
  9. data/docs/docs/getting-started/_category_.json +4 -0
  10. data/docs/docs/getting-started/advanced-mode.md +46 -0
  11. data/docs/docs/getting-started/configuration.md +47 -0
  12. data/docs/docs/getting-started/search-matches.md +67 -0
  13. data/docs/docs/getting-started/simple-mode.md +284 -0
  14. data/docs/docs/getting-started/sorting.md +79 -0
  15. data/docs/docs/getting-started/using-predicates.md +282 -0
  16. data/docs/docs/going-further/_category_.json +4 -0
  17. data/docs/docs/going-further/associations.md +70 -0
  18. data/docs/docs/going-further/custom-predicates.md +52 -0
  19. data/docs/docs/going-further/documentation.md +31 -0
  20. data/docs/docs/going-further/exporting-to-csv.md +49 -0
  21. data/docs/docs/going-further/external-guides.md +57 -0
  22. data/docs/docs/going-further/form-customisation.md +63 -0
  23. data/docs/docs/going-further/i18n.md +53 -0
  24. data/docs/{img → docs/going-further/img}/create_release.png +0 -0
  25. data/docs/docs/going-further/merging-searches.md +41 -0
  26. data/docs/docs/going-further/other-notes.md +428 -0
  27. data/docs/docs/going-further/ransackers.md +331 -0
  28. data/docs/docs/going-further/release_process.md +36 -0
  29. data/docs/docs/going-further/saving-queries.md +82 -0
  30. data/docs/docs/going-further/searching-postgres.md +57 -0
  31. data/docs/docs/intro.md +99 -0
  32. data/docs/docusaurus.config.js +108 -0
  33. data/docs/package-lock.json +9207 -0
  34. data/docs/package.json +37 -0
  35. data/docs/sidebars.js +31 -0
  36. data/docs/src/components/HomepageFeatures/index.js +64 -0
  37. data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  38. data/docs/src/css/custom.css +39 -0
  39. data/docs/src/pages/index.module.css +23 -0
  40. data/docs/src/pages/markdown-page.md +7 -0
  41. data/docs/static/.nojekyll +0 -0
  42. data/docs/static/img/docusaurus.png +0 -0
  43. data/docs/static/img/favicon.ico +0 -0
  44. data/docs/static/img/logo.svg +1 -0
  45. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  46. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  47. data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  48. data/docs/static/img/undraw_docusaurus_react.svg +170 -0
  49. data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  50. data/{logo → docs/static/logo}/ransack-h.png +0 -0
  51. data/{logo → docs/static/logo}/ransack-h.svg +0 -0
  52. data/{logo → docs/static/logo}/ransack-v.png +0 -0
  53. data/{logo → docs/static/logo}/ransack-v.svg +0 -0
  54. data/{logo → docs/static/logo}/ransack.png +0 -0
  55. data/{logo → docs/static/logo}/ransack.svg +0 -0
  56. data/docs/yarn.lock +7671 -0
  57. data/lib/ransack/adapters/active_record/base.rb +0 -2
  58. data/lib/ransack/adapters/active_record/context.rb +1 -0
  59. data/lib/ransack/helpers/form_helper.rb +10 -2
  60. data/lib/ransack/search.rb +2 -2
  61. data/lib/ransack/version.rb +1 -1
  62. data/ransack.gemspec +2 -2
  63. data/spec/ransack/adapters/active_record/base_spec.rb +10 -1
  64. data/spec/ransack/helpers/form_helper_spec.rb +32 -0
  65. data/spec/ransack/search_spec.rb +23 -0
  66. data/spec/support/schema.rb +16 -0
  67. metadata +58 -12
  68. data/docs/release_process.md +0 -17
@@ -0,0 +1,282 @@
1
+ ---
2
+ title: Using Predicates
3
+ ---
4
+
5
+ The primary method of searching in Ransack is by using what is known as *predicates*.
6
+
7
+ Predicates are used within Ransack search queries to determine what information to
8
+ match. For instance, the `cont` predicate will check to see if an attribute called
9
+ "first_name" contains a value using a wildcard query:
10
+
11
+ ```ruby
12
+ >> User.ransack(first_name_cont: 'Rya').result.to_sql
13
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE '%Rya%')
14
+ ```
15
+
16
+ You can also combine predicates for OR queries:
17
+ ```ruby
18
+ >> User.ransack(first_name_or_last_name_cont: 'Rya').result.to_sql
19
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE '%Rya%'
20
+ OR "users"."last_name" LIKE '%Rya%')
21
+ ```
22
+
23
+ The syntax for `OR` queries on an associated model is not immediately obvious, but makes sense. Assuming a `User` `has_one` `Account` and the `Account` has `attributes` `foo` and `bar`:
24
+
25
+ ```ruby
26
+ >> User.ransack(account_foo_or_account_bar: 'val').result.to_sql
27
+ => SELECT "users".* FROM "users" INNER JOIN accounts ON accounts.user_id = users.id WHERE ("accounts.foo LIKE '%val%' OR accounts.bar LIKE '%val%')
28
+ ```
29
+
30
+ Below is a list of the built-in predicates of Ransack and their opposites. You may already
31
+ be familiar with some of the predicates, as they also exist in the ARel library.
32
+
33
+ If you want to add your own, please
34
+ see the [[Custom-Predicates|Custom Predicates]] page.
35
+
36
+ **Please note:** any attempt to use a predicate for an attribute that does not exist will
37
+ *silently fail*. For instance, this will not work when there is no `name` attribute:
38
+
39
+ ```ruby
40
+ >> User.ransack(name_cont: 'Rya').result.to_sql
41
+ => "SELECT "users".* FROM "users"
42
+ ```
43
+
44
+ ## eq (equals)
45
+
46
+ The `eq` predicate returns all records where a field is *exactly* equal to a given value:
47
+
48
+ ```ruby
49
+ >> User.ransack(first_name_eq: 'Ryan').result.to_sql
50
+ => SELECT "users".* FROM "users" WHERE "users"."first_name" = 'Ryan'
51
+ ```
52
+
53
+ **Opposite: `not_eq`**
54
+
55
+ ## matches
56
+
57
+ The `matches` predicate returns all records where a field is like a given value:
58
+
59
+ ```ruby
60
+ >> User.ransack(first_name_matches: 'Ryan').result.to_sql
61
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE 'Ryan')
62
+ ```
63
+
64
+ On Postgres, the case-insensitive ILIKE will be used.
65
+
66
+ **Opposite: `does_not_match`**
67
+
68
+ *Note: If you want to do wildcard matching, you may be looking for the `cont`/`not_cont`
69
+ predicates instead.*
70
+
71
+ ## lt (less than)
72
+
73
+ The `lt` predicate returns all records where a field is less than a given value:
74
+
75
+ ```ruby
76
+ >> User.ransack(age_lt: 25).result.to_sql
77
+ => SELECT "users".* FROM "users" WHERE ("users"."age" < 25)
78
+ ```
79
+
80
+ **Opposite: `gteq` (greater than or equal to)**
81
+
82
+ ## lteq (less than or equal to)
83
+
84
+ The `lteq` predicate returns all records where a field is less than *or equal to* a given value:
85
+
86
+ ```ruby
87
+ >> User.ransack(age_lteq: 25).result.to_sql
88
+ => SELECT "users".* FROM "users" WHERE ("users"."age" <= 25)
89
+ ```
90
+
91
+ **Opposite: `gt` (greater than)**
92
+
93
+ ## in
94
+
95
+ The `in` predicate returns all records where a field is within a specified list:
96
+
97
+ ```ruby
98
+ >> User.ransack(age_in: 20..25).result.to_sql
99
+ => SELECT "users".* FROM "users" WHERE "users"."age" IN (20, 21, 22, 23, 24, 25)
100
+ ```
101
+
102
+ It can also take an array:
103
+
104
+ ```ruby
105
+ >> User.ransack(age_in: [20, 21, 22, 23, 24, 25]).result.to_sql
106
+ => SELECT "users".* FROM "users" WHERE "users"."age" IN (20, 21, 22, 23, 24, 25)
107
+ ```
108
+
109
+ **Opposite: `not_in`**
110
+
111
+ ## cont
112
+
113
+ The `cont` predicate returns all records where a field contains a given value:
114
+
115
+ ```ruby
116
+ >> User.ransack(first_name_cont: 'Rya').result.to_sql
117
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE '%Rya%')
118
+ ```
119
+
120
+ **Opposite: `not_cont`**
121
+
122
+ ## cont_any (contains any)
123
+
124
+ The `cont_any` predicate returns all records where a field contains any of the given values:
125
+
126
+ ```ruby
127
+ >> User.ransack(first_name_cont_any: %w(Rya Lis)).result.to_sql
128
+ => SELECT "users".* FROM "users" WHERE (("users"."first_name" LIKE '%Rya%' OR "users"."first_name" LIKE '%Lis%'))
129
+ ```
130
+
131
+ **Opposite: `not_cont_any`**
132
+
133
+
134
+ ## cont_all (contains all)
135
+
136
+ The `cont_all` predicate returns all records where a field contains all of the given values:
137
+
138
+ ```ruby
139
+ >> User.ransack(city_cont_all: %w(Grand Rapids)).result.to_sql
140
+ => SELECT "users".* FROM "users" WHERE (("users"."city" LIKE '%Grand%' AND "users"."city" LIKE '%Rapids%'))
141
+ ```
142
+
143
+ **Opposite: `not_cont_all`**
144
+
145
+
146
+ ## i_cont
147
+
148
+ The `i_cont` case-insensitive predicate returns all records where a field contains a given value and ignores case:
149
+
150
+ ```ruby
151
+ >> User.ransack(first_name_i_cont: 'Rya').result.to_sql
152
+ => SELECT "users".* FROM "users" WHERE (LOWER("users"."first_name") LIKE '%rya%')
153
+ ```
154
+
155
+ **Opposite: `not_i_cont`**
156
+
157
+ ## i_cont_any
158
+
159
+ The `i_cont_any` case-insensitive predicate returns all records where a field contains any of the given values and ignores case:
160
+
161
+ ```ruby
162
+ >> User.ransack(first_name_i_cont_any: %w(Rya Lis)).result.to_sql
163
+ => SELECT "users".* FROM "users" WHERE ((LOWER("users"."first_name") LIKE '%rya%' OR LOWER("users"."first_name") LIKE '%lis%'))
164
+ ```
165
+
166
+ **Opposite: `not_i_cont_any`**
167
+
168
+
169
+ ## i_cont_all
170
+
171
+ The `i_cont_all` case-insensitive predicate returns all records where a field contains all of the given values and ignores case:
172
+
173
+ ```ruby
174
+ >> User.ransack(city_i_cont_all: %w(Grand Rapids)).result.to_sql
175
+ => SELECT "users".* FROM "users" WHERE ((LOWER("users"."city") LIKE '%grand%' AND LOWER("users"."city") LIKE '%rapids%'))
176
+ ```
177
+
178
+ **Opposite: `not_i_cont_all`**
179
+
180
+ ## start (starts with)
181
+
182
+ The `start` predicate returns all records where a field begins with a given value:
183
+
184
+ ```ruby
185
+ >> User.ransack(first_name_start: 'Rya').result.to_sql
186
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE 'Rya%')
187
+ ```
188
+
189
+ **Opposite: `not_start`**
190
+
191
+ ## end (ends with)
192
+
193
+ The `end` predicate returns all records where a field ends with a given value:
194
+
195
+ ```ruby
196
+ >> User.ransack(first_name_end: 'yan').result.to_sql
197
+ => SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE '%yan')
198
+ ```
199
+
200
+ **Opposite: `not_end`**
201
+
202
+ ## true
203
+
204
+ The `true` predicate returns all records where a field is true. The '1' indicates that
205
+ to Ransack that you indeed want to check the truthiness of this field. The other truthy
206
+ values are 'true', 'TRUE', 't' or 'T'.
207
+
208
+ ```ruby
209
+ >> User.ransack(awesome_true: '1').result.to_sql
210
+ => SELECT "users".* FROM "users" WHERE ("users"."awesome" = 't')
211
+ ```
212
+
213
+ *Note: different database systems use different values to represent truth. In the above
214
+ example, we are using SQLite3.*
215
+
216
+ **Opposite: `not_true`**
217
+
218
+ ## false
219
+
220
+ The `false` predicate returns all records where a field is false.
221
+
222
+ ```ruby
223
+ >> User.ransack(awesome_false: '1').result.to_sql
224
+ => SELECT "users".* FROM "users" WHERE ("users"."awesome" = 'f')
225
+ ```
226
+
227
+ **Opposite: `not_false`**
228
+
229
+ *Note: the `false` predicate may be considered the opposite of the `true` predicate if the field does not contain `null` values. Otherwise, use `not_false`.*
230
+
231
+ ## present
232
+
233
+ The `present` predicate returns all records where a field is present (not null and not a
234
+ blank string).
235
+
236
+ ```ruby
237
+ >> User.ransack(first_name_present: '1').result.to_sql
238
+ => SELECT "users".* FROM "users" WHERE (("users"."first_name" IS NOT NULL AND "users"."first_name" != ''))
239
+ ```
240
+
241
+ **Opposite: `blank`**
242
+
243
+ ## null
244
+
245
+ The `null` predicate returns all records where a field is null:
246
+
247
+ ```ruby
248
+ >> User.ransack(first_name_null: 1).result.to_sql
249
+ => SELECT "users".* FROM "users" WHERE "users"."first_name" IS NULL
250
+ ```
251
+
252
+ **Opposite: `not_null`**
253
+
254
+ # URL parameter structure
255
+
256
+ The search parameters are passed to ransack as a hash. The URL representation of this hash uses the bracket notation: ```hash_name[key]=value```. The hash_name is the parameter which is defined in the controller, for instance ```q```. The key is the attribute and search predicate compound, for instance ```first_name_cont```, the value is the search parameter. When searching without using the search form helpers this URL structure needs to be created manually.
257
+
258
+ For example, the URL layout for searching and sorting users could looks like this:
259
+
260
+ ```
261
+ /users.json?q[first_name_cont]=pete&q[last_name_cont]=jack&q[s]=created_at+desc
262
+ ```
263
+
264
+ _Note that the sorting parameter ```s``` is nested within the ```q``` hash._
265
+
266
+ When using JavaScript to create such a URL, a matching jQuery request could look like this:
267
+
268
+ ```javascript
269
+ $.ajax({
270
+ url: "/users.json",
271
+ data: {
272
+ q: {
273
+ first_name_cont: "pete",
274
+ last_name_cont: "jack",
275
+ s: "created_at desc"
276
+ }
277
+ },
278
+ success: function (data){
279
+ console.log(data);
280
+ }
281
+ });
282
+ ```
@@ -0,0 +1,4 @@
1
+ {
2
+ "label": "Going further",
3
+ "position": 2
4
+ }
@@ -0,0 +1,70 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: Associations
4
+ ---
5
+
6
+ ### Associations
7
+
8
+ You can easily use Ransack to search for objects in `has_many` and `belongs_to`
9
+ associations.
10
+
11
+ Given these associations...
12
+
13
+ ```ruby
14
+ class Employee < ActiveRecord::Base
15
+ belongs_to :supervisor
16
+
17
+ # has attributes first_name:string and last_name:string
18
+ end
19
+
20
+ class Department < ActiveRecord::Base
21
+ has_many :supervisors
22
+
23
+ # has attribute title:string
24
+ end
25
+
26
+ class Supervisor < ActiveRecord::Base
27
+ belongs_to :department
28
+ has_many :employees
29
+
30
+ # has attribute last_name:string
31
+ end
32
+ ```
33
+
34
+ ... and a controller...
35
+
36
+ ```ruby
37
+ class SupervisorsController < ApplicationController
38
+ def index
39
+ @q = Supervisor.ransack(params[:q])
40
+ @supervisors = @q.result.includes(:department, :employees)
41
+ end
42
+ end
43
+ ```
44
+
45
+ ... you might set up your form like this...
46
+
47
+ ```erb
48
+ <%= search_form_for @q do |f| %>
49
+ <%= f.label :last_name_cont %>
50
+ <%= f.search_field :last_name_cont %>
51
+
52
+ <%= f.label :department_title_cont %>
53
+ <%= f.search_field :department_title_cont %>
54
+
55
+ <%= f.label :employees_first_name_or_employees_last_name_cont %>
56
+ <%= f.search_field :employees_first_name_or_employees_last_name_cont %>
57
+
58
+ <%= f.submit "search" %>
59
+ <% end %>
60
+ ...
61
+ <%= content_tag :table do %>
62
+ <%= content_tag :th, sort_link(@q, :last_name) %>
63
+ <%= content_tag :th, sort_link(@q, :department_title) %>
64
+ <%= content_tag :th, sort_link(@q, :employees_last_name) %>
65
+ <% end %>
66
+ ```
67
+
68
+ If you have trouble sorting on associations, try using an SQL string with the
69
+ pluralized table (`'departments.title'`,`'employees.last_name'`) instead of the
70
+ symbolized association (`:department_title)`, `:employees_last_name`).
@@ -0,0 +1,52 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: Custom predicates
4
+ ---
5
+
6
+ If you'd like to add your own custom Ransack predicates:
7
+
8
+ ```ruby
9
+ # config/initializers/ransack.rb
10
+
11
+ Ransack.configure do |config|
12
+ config.add_predicate 'equals_diddly', # Name your predicate
13
+ # What non-compound ARel predicate will it use? (eq, matches, etc)
14
+ arel_predicate: 'eq',
15
+ # Format incoming values as you see fit. (Default: Don't do formatting)
16
+ formatter: proc { |v| "#{v}-diddly" },
17
+ # Validate a value. An "invalid" value won't be used in a search.
18
+ # Below is default.
19
+ validator: proc { |v| v.present? },
20
+ # Should compounds be created? Will use the compound (any/all) version
21
+ # of the arel_predicate to create a corresponding any/all version of
22
+ # your predicate. (Default: true)
23
+ compounds: true,
24
+ # Force a specific column type for type-casting of supplied values.
25
+ # (Default: use type from DB column)
26
+ type: :string,
27
+ # Use LOWER(column on database).
28
+ # (Default: false)
29
+ case_insensitive: true
30
+ end
31
+ ```
32
+ You can check all Arel predicates [here](https://github.com/rails/rails/blob/main/activerecord/lib/arel/predications.rb).
33
+
34
+ If Arel does not have the predicate you are looking for, consider monkey patching it:
35
+
36
+ ```ruby
37
+ # config/initializers/ransack.rb
38
+
39
+ module Arel
40
+ module Predications
41
+ def gteq_or_null(other)
42
+ left = gteq(other)
43
+ right = eq(nil)
44
+ left.or(right)
45
+ end
46
+ end
47
+ end
48
+
49
+ Ransack.configure do |config|
50
+ config.add_predicate 'gteq_or_null', arel_predicate: 'gteq_or_null'
51
+ end
52
+ ```
@@ -0,0 +1,31 @@
1
+ ---
2
+ sidebar_position: 11
3
+ title: Documentation
4
+ ---
5
+
6
+ Ransack uses [Docusaurus](https://docusaurus.io/) for documentation. To contribute to the docs simply use the "Edit this page" link from any page to directly edit, or else pull the repo and edit locally.
7
+
8
+ ### Local Development
9
+
10
+ ```
11
+ cd docs
12
+ yarn start
13
+ ```
14
+
15
+ This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
16
+
17
+ ### Build
18
+
19
+ ```
20
+ yarn build
21
+ ```
22
+
23
+ This command generates static content into the `build` directory and can be served using any static contents hosting service.
24
+
25
+ ### Deployment
26
+
27
+ Using SSH:
28
+
29
+ ```
30
+ USE_SSH=true yarn deploy
31
+ ```
@@ -0,0 +1,49 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: CSV Export
4
+ ---
5
+
6
+ Exporting to CSV
7
+
8
+ Example downloading a csv file preserving ransack search, based on [this gist](https://gist.github.com/pama/adff25ed1f4b796ce088ea362a08e1c5)
9
+
10
+ ```jsx title='index.html.erb'
11
+ <h1>Users</h1>
12
+
13
+ <%= search_form_for @q, url: dashboard_index_path do |f| %>
14
+ <%= f.label :name_cont %>
15
+ <%= f.search_field :name_cont %>
16
+
17
+ <%= f.submit %>
18
+ <% end %>
19
+
20
+ <ul>
21
+ <% @users.each do |user| %>
22
+ <li><%= user.name %> [<%= user.devices.map {|device| device.name }.join(', ') %>]</li>
23
+ <% end %>
24
+ </ul>
25
+
26
+ <% if params[:q] %>
27
+ <%= link_to 'Export 1', dashboard_index_path({name: params[:q][:name_cont]}.merge({format: :csv})) %>
28
+ <% else %>
29
+ <%= link_to 'Export 2', dashboard_index_path(format: 'csv') %>
30
+ <% end %>
31
+ ```
32
+
33
+ ```jsx title='user.rb'
34
+ require 'csv'
35
+
36
+ class User < ApplicationRecord
37
+ has_many :devices
38
+
39
+ def self.get_csv(users)
40
+ CSV.generate do |csv|
41
+ csv << ["Name", "Devices"]
42
+
43
+ users.each do |user|
44
+ csv << [user.name, user.devices.map{|device| device.name}.join(', ')]
45
+ end
46
+ end
47
+ end
48
+ end
49
+ ```
@@ -0,0 +1,57 @@
1
+ ---
2
+ sidebar_position: 9
3
+ title: External resources
4
+ ---
5
+
6
+ There is a plethora of material on Ransack around the internet. We've collected some here for your convenience.
7
+
8
+ Do you want to have a blog post or other content on Ransack highlighted? Please just edit the page, add your content and a Pull Request will be sent to Ransack maintainers for approval.
9
+
10
+ # Screencasts
11
+
12
+ - [DriftingRuby: Ransack Search and Hotwire](https://www.driftingruby.com/episodes/ransack-search-and-hotwire)
13
+ - [GoRails: Forum Series Part 6: Search with Ransack](https://gorails.com/episodes/forum-search-with-ransack)
14
+ - [Railscast 370 - Ransack](http://railscasts.com/episodes/370-ransack)
15
+ - [Search And Sort Ransack Associations With The Rails Ransack Gem | Ruby On Rails 6 Ransack Tutorial](https://www.youtube.com/watch?v=rtg-5EXwpbg)
16
+
17
+
18
+ # Gems
19
+
20
+ - [ActiveAdmin](https://activeadmin.info/) The Administration Framework for Rails **_uses Ransack internally_**
21
+ - [Ransack Memory](https://github.com/richardrails/ransack_memory) Automatically save and load Ransack's filtered params into the Rail's session
22
+ - [Mobility Ransack](https://github.com/shioyama/mobility-ransack) Search attributes translated by Mobility with Ransack.
23
+ - [Ransack UI](https://github.com/ndbroadbent/ransack_ui) Framework for building a search UI with Ransack **_seems abandoned_**
24
+
25
+ # Blogs
26
+
27
+ - [Search And Sort In Ruby On Rails 6 With The Ransack Gem](https://deanin.com/blog/ransack/)
28
+ - [Implement Ransack Gem in Ruby on Rails](https://www.botreetechnologies.com/blog/implementing-advanced-search-in-ruby-on-rails-with-ransack/)
29
+ - [Searching and Sorting with Ransack](https://jaspercurry.medium.com/searching-and-sorting-on-rails-with-ransack-560e862e650a)
30
+ - [How to Build Your Own ActiveAdmin Filters with Ransack](https://www.viget.com/articles/how-to-build-your-own-filters-with-ransack/)
31
+ - [Avoid Ransack's N+1 Pitfall!](https://dev.to/husteadrobert/avoid-ransacks-n1-pitfall-33of)
32
+ - [Filter and paging with Kaminari](https://gist.github.com/MyklClason/e4dc96fd0e009b7b3a9c84ddbb1e11d2)
33
+ - [Pagination for Ransack Forms](https://nicholaide.github.io/ransack/2016/11/26/ransack-pagination.html)
34
+ - [AJAX Search, Sort, Paginate with Ransack and Kaminari](https://techbrownbags.wordpress.com/2014/01/17/rails-ajax-search-sort-paginate-with-ransack-kaminari/)
35
+ - [Searching with Ransack in Ruby on Rails](http://blog.magmalabs.io/2019/03/12/searching-with-ransack-in-ruby-on-rails.html)
36
+ - [Role scopes with gem Ransack](https://blog.corsego.com/rolify-scopes)
37
+ - [Searching and Sorting with Ransack](https://www.mintbit.com/blog/searching-and-sorting-with-ransack)
38
+ - [Using custom scopes with Ransack gem in Rails](https://profilehunt.net/blog/using-custom-scopes-with-ransack-in-rails)
39
+ - [Query Date Range With Ransack](https://lingceng.github.io/blog/2015/12/28/query-date-range-with-ransack/)
40
+ - [ransack vs searchkick: Building a search feature in Rails](https://www.cookieshq.co.uk/posts/ransack-vs-searchkick-building-a-search-feature-in-rails)
41
+ - [Using ransack and delegate in Rails](https://huangwenwei.com/blogs/using-ransack-and-delegate-in-rails)
42
+ - [Using Ransack as a Search Engine](https://medium.com/@jelaniwoods/using-ransack-as-a-search-engine-92e002a68da)
43
+ - [Advanced Search with Ransack](https://www.sitepoint.com/advanced-search-ransack/)
44
+ - [Sort a table of records in Rails with Ransack](https://alankydd.wordpress.com/2012/03/12/sort-a-table-of-records-in-rails-with-ransack/)
45
+ - [Ransack: Search with Multiple Checkboxes (Rails)](https://iamjosh.wordpress.com/2014/03/07/ransack-search-with-multiple-checkboxes/)
46
+ - [Rails : Ransack : Sorting data by ratings](https://cbabhusal.wordpress.com/2017/01/03/rails-ransack-sorting-data-by-ratings/)
47
+ - [Setting Up Rails 5 API Only App with ActiveAdmin enabled](https://rrott.com/blog/ror/rails-5-api-with-activeadmin-integration/)
48
+ - [Ransack, the library formerly known as MetaSearch 2.0](https://ernie.io/2011/04/01/ransack-the-library-formerly-known-as-metasearch-2-0/) **_some Ransack history_**
49
+
50
+ ## In French
51
+
52
+ - [Faciliter les recherches avec Ransack](https://www.synbioz.com/blog/tech/faciliter-les-recherches-avec-ransack)
53
+
54
+ ## In Vietnamese
55
+
56
+ - [Ransack - công cụ tuyệt vời giúp tìm kiếm và sắp xếp dữ liệu đơn giản hơn
57
+ ](https://nddblog.com/posts/ransack-cong-cu-tuyet-voi-giup-tim-kiem-va-sap-xep-du-lieu-don-gian-hon)
@@ -0,0 +1,63 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: Form customisation
4
+ ---
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/activerecord-hackery/ransack/tree/master/lib/ransack/locale) for more examples):
7
+
8
+ ```yml
9
+ # locales/en.yml
10
+ en:
11
+ ransack:
12
+ asc: ascending
13
+ desc: descending
14
+ predicates:
15
+ cont: contains
16
+ not_cont: not contains
17
+ start: starts with
18
+ end: ends with
19
+ gt: greater than
20
+ lt: less than
21
+ attributes:
22
+ person:
23
+ name: Full Name
24
+ article:
25
+ title: Article Title
26
+ body: Main Content
27
+ ```
28
+ The names of attribute fields may also be changed globally or under activerecord:
29
+
30
+ ```yml
31
+ # locales/en.yml
32
+ en:
33
+ attributes:
34
+ model_name:
35
+ model_field1: field name1
36
+ model_field2: field name2
37
+ activerecord:
38
+ attributes:
39
+ namespace/article:
40
+ title: AR Namespaced Title
41
+ namespace_article:
42
+ title: Old Ransack Namespaced Title
43
+ ```
44
+
45
+ To limit the predicates in the `predicate_select` form helper in a view template, pass an array of permitted predicates with `only`:
46
+
47
+ ```erb
48
+ <%= f.predicate_select only: %i(cont not_cont eq not_eq blank null) %>
49
+ ```
50
+
51
+ Compound predicates (`_any` & `_all`) may be removed by passing the option `compounds: false`.
52
+
53
+ ```erb
54
+ <%= f.predicate_select compounds: false %>
55
+ ```
56
+
57
+ Searchable attributes versus non-searchable ones may be specified as follows:
58
+
59
+ ```ruby
60
+ def self.ransackable_attributes(auth_object = nil)
61
+ %w(searchable_attribute_1 searchable_attribute_2 ...) + _ransackers.keys
62
+ end
63
+ ```
@@ -0,0 +1,53 @@
1
+ ---
2
+ sidebar_position: 3
3
+ title: i18n
4
+ ---
5
+
6
+ # i18n and Ransack
7
+
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
10
+ many translations for Ransack available at
11
+ http://www.localeapp.com/projects/2999.
12
+
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):
15
+
16
+ locales/en.yml:
17
+ ```yml
18
+ en:
19
+ ransack:
20
+ asc: ascending
21
+ desc: descending
22
+ predicates:
23
+ cont: contains
24
+ not_cont: not contains
25
+ start: starts with
26
+ end: ends with
27
+ gt: greater than
28
+ lt: less than
29
+ models:
30
+ person: Passanger
31
+ attributes:
32
+ person:
33
+ name: Full Name
34
+ article:
35
+ title: Article Title
36
+ body: Main Content
37
+ ```
38
+
39
+ Attribute names may also be changed globally, or under `activerecord`:
40
+
41
+ ```yml
42
+ en:
43
+ attributes:
44
+ model_name:
45
+ model_field1: field name1
46
+ model_field2: field name2
47
+ activerecord:
48
+ attributes:
49
+ namespace/article:
50
+ title: AR Namespaced Title
51
+ namespace_article:
52
+ title: Old Ransack Namespaced Title
53
+ ```