ransack 1.8.2 → 1.8.3
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/.travis.yml +14 -15
- data/CHANGELOG.md +43 -0
- data/README.md +89 -39
- data/lib/ransack.rb +0 -7
- data/lib/ransack/adapters/active_record.rb +11 -1
- data/lib/ransack/adapters/active_record/base.rb +2 -1
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +7 -2
- data/lib/ransack/adapters/mongoid.rb +2 -0
- data/lib/ransack/adapters/mongoid/base.rb +6 -17
- data/lib/ransack/configuration.rb +41 -1
- data/lib/ransack/helpers/form_helper.rb +2 -2
- data/lib/ransack/search.rb +8 -2
- data/lib/ransack/version.rb +1 -1
- data/spec/mongoid/adapters/mongoid/base_spec.rb +21 -2
- data/spec/mongoid/configuration_spec.rb +71 -11
- data/spec/mongoid/search_spec.rb +0 -1
- data/spec/mongoid/support/schema.rb +3 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +41 -14
- data/spec/ransack/configuration_spec.rb +72 -14
- data/spec/ransack/helpers/form_helper_spec.rb +104 -2
- data/spec/ransack/predicate_spec.rb +22 -0
- data/spec/support/schema.rb +3 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d068e0ef0efe6ce1a4afdb11cc36361f94bbcf68
|
4
|
+
data.tar.gz: 2ab905dd3037f405cfc262e2440cbfa557c5a799
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 354a8a5fc605f5efb7da6d1b78544f93780293418ac9a4578ae395fb608dbd69d301d5a129fbc6cf20c46427427fbeba04b0f7ea040b54771aaecbd31cf174ac
|
7
|
+
data.tar.gz: 388a7b733a5460acd980703c6d918077fc27e4777f8acf0b2f3c72b696664c1ef9997c477de74a772ea776eb56521d65cda03bb7f190441575801a4d65b479d6
|
data/.travis.yml
CHANGED
@@ -3,11 +3,10 @@ language: ruby
|
|
3
3
|
sudo: false
|
4
4
|
|
5
5
|
rvm:
|
6
|
-
- 2.3.
|
7
|
-
- 2.2.
|
6
|
+
- 2.3.3
|
7
|
+
- 2.2.6
|
8
8
|
- 2.1.10
|
9
9
|
- 2.0
|
10
|
-
- 1.9
|
11
10
|
|
12
11
|
env:
|
13
12
|
- RAILS=5-0-stable DB=sqlite3
|
@@ -50,26 +49,26 @@ matrix:
|
|
50
49
|
- rvm: 2.0
|
51
50
|
env: RAILS=5-0-stable DB=postgres
|
52
51
|
|
53
|
-
- rvm:
|
54
|
-
env: RAILS=
|
55
|
-
- rvm:
|
56
|
-
env: RAILS=
|
57
|
-
- rvm:
|
58
|
-
env: RAILS=
|
52
|
+
- rvm: 2.0
|
53
|
+
env: RAILS=4-2-stable DB=sqlite3
|
54
|
+
- rvm: 2.0
|
55
|
+
env: RAILS=4-2-stable DB=mysql
|
56
|
+
- rvm: 2.0
|
57
|
+
env: RAILS=4-2-stable DB=postgres
|
59
58
|
|
60
59
|
include:
|
61
|
-
- rvm: 2.3.
|
60
|
+
- rvm: 2.3.3
|
62
61
|
env: RAILS=master DB=sqlite3
|
63
|
-
- rvm: 2.3.
|
62
|
+
- rvm: 2.3.3
|
64
63
|
env: RAILS=master DB=mysql
|
65
|
-
- rvm: 2.3.
|
64
|
+
- rvm: 2.3.3
|
66
65
|
env: RAILS=master DB=postgres
|
67
66
|
|
68
|
-
- rvm: 2.2.
|
67
|
+
- rvm: 2.2.6
|
69
68
|
env: RAILS=master DB=sqlite3
|
70
|
-
- rvm: 2.2.
|
69
|
+
- rvm: 2.2.6
|
71
70
|
env: RAILS=master DB=mysql
|
72
|
-
- rvm: 2.2.
|
71
|
+
- rvm: 2.2.6
|
73
72
|
env: RAILS=master DB=postgres
|
74
73
|
|
75
74
|
allow_failures:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,48 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## Unreleased
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* Add a config option to customize the up and down arrows used for direction
|
8
|
+
indicators in Ransack sort links.
|
9
|
+
PR [#726](https://github.com/activerecord-hackery/ransack/pull/726).
|
10
|
+
|
11
|
+
*Garett Arrowood*
|
12
|
+
|
13
|
+
* Add ability to turn off sanitization of custom scope arguments.
|
14
|
+
PR [#742](https://github.com/activerecord-hackery/ransack/pull/742).
|
15
|
+
|
16
|
+
*Garett Arrowood*
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
* Use class attributes properly so that inheritance is respected.
|
21
|
+
PR [#717](https://github.com/activerecord-hackery/ransack/pull/717).
|
22
|
+
This fixes two bugs:
|
23
|
+
|
24
|
+
1. In the Mongoid adapter, subclasses were not properly inheriting their
|
25
|
+
parents' Ransack aliases because each class defined its own set of
|
26
|
+
aliases.
|
27
|
+
|
28
|
+
2. In the Active Record adapter, Ransack aliases were defined in such a way
|
29
|
+
that the parent's (and grandparent's, etc.) aliases were overwritten by
|
30
|
+
the child, meaning that all aliases were ultimately kept on
|
31
|
+
`ActiveRecord::Base`. This had the unfortunate effect of enforcing
|
32
|
+
uniqueness of Ransack alias names across all models rather than per
|
33
|
+
model. Depending on the load order of models, earlier definitions of an
|
34
|
+
alias in other models were clobbered.
|
35
|
+
|
36
|
+
*Steve Richert (laserlemon)*
|
37
|
+
|
38
|
+
* Use `ActiveSupport.on_load` hooks to include Ransack in Active Record,
|
39
|
+
avoiding autoloading the constant too soon. PR
|
40
|
+
[#719](https://github.com/activerecord-hackery/ransack/pull/719). Reference:
|
41
|
+
[This comment in rails#23589]
|
42
|
+
(https://github.com/rails/rails/issues/23589#issuecomment-229247727).
|
43
|
+
|
44
|
+
*Yuji Yaginuma (y-yagi)*
|
45
|
+
|
3
46
|
## Version 1.8.2 - 2016-08-08
|
4
47
|
### Fixed
|
5
48
|
|
data/README.md
CHANGED
@@ -7,20 +7,21 @@
|
|
7
7
|
[]
|
8
8
|
(https://codeclimate.com/github/activerecord-hackery/ransack)
|
9
9
|
|
10
|
-
Ransack is a rewrite of [MetaSearch]
|
11
|
-
(https://github.com/activerecord-hackery/meta_search)
|
10
|
+
Ransack is a rewrite of [MetaSearch](https://github.com/activerecord-hackery/meta_search)
|
12
11
|
created by [Ernie Miller](http://twitter.com/erniemiller)
|
13
|
-
and maintained
|
14
|
-
[Jon Atack](http://twitter.com/jonatack) and
|
15
|
-
(
|
12
|
+
and developed/maintained for years by
|
13
|
+
[Jon Atack](http://twitter.com/jonatack) and
|
14
|
+
[Ryan Bigg](http://twitter.com/ryanbigg) with the help of a great group of
|
15
|
+
[contributors](https://github.com/activerecord-hackery/ransack/graphs/contributors).
|
16
16
|
While it supports many of the same features as MetaSearch, its underlying
|
17
17
|
implementation differs greatly from MetaSearch,
|
18
18
|
and backwards compatibility is not a design goal.
|
19
19
|
|
20
|
-
Ransack enables the creation of both
|
21
|
-
[
|
22
|
-
|
23
|
-
|
20
|
+
Ransack enables the creation of both
|
21
|
+
[simple](http://ransack-demo.herokuapp.com) and
|
22
|
+
[advanced](http://ransack-demo.herokuapp.com/users/advanced_search) search forms
|
23
|
+
for your Ruby on Rails application
|
24
|
+
([demo source code here](https://github.com/activerecord-hackery/ransack_demo)).
|
24
25
|
If you're looking for something that simplifies query generation at the model
|
25
26
|
or controller layer, you're probably not looking for Ransack (or MetaSearch,
|
26
27
|
for that matter). Try [Squeel](https://github.com/activerecord-hackery/squeel)
|
@@ -56,11 +57,6 @@ branch:
|
|
56
57
|
gem 'ransack', github: 'activerecord-hackery/ransack'
|
57
58
|
```
|
58
59
|
|
59
|
-
If you are using Rails 5 or master and need pagination compatible with it and
|
60
|
-
Ransack, there is a [Rails 5 version of the `will_paginate` gem here](https://github.com/jonatack/will_paginate).
|
61
|
-
It is also optimized for Ruby 2.2+. To use it, in your Gemfile:
|
62
|
-
`gem 'will_paginate', github: 'jonatack/will_paginate'`.
|
63
|
-
|
64
60
|
## Issues tracker
|
65
61
|
|
66
62
|
* Before filing an issue, please read the [Contributing Guide](CONTRIBUTING.md).
|
@@ -82,8 +78,7 @@ If you're coming from MetaSearch, things to note:
|
|
82
78
|
1. The default param key for search params is now `:q`, instead of `:search`.
|
83
79
|
This is primarily to shorten query strings, though advanced queries (below)
|
84
80
|
will still run afoul of URL length limits in most browsers and require a
|
85
|
-
switch to HTTP POST requests. This key is [configurable]
|
86
|
-
(https://github.com/activerecord-hackery/ransack/wiki/Configuration).
|
81
|
+
switch to HTTP POST requests. This key is [configurable](https://github.com/activerecord-hackery/ransack/wiki/Configuration).
|
87
82
|
|
88
83
|
2. `form_for` is now `search_form_for`, and validates that a Ransack::Search
|
89
84
|
object is passed to it.
|
@@ -93,7 +88,7 @@ If you're coming from MetaSearch, things to note:
|
|
93
88
|
ActiveRecord::Relation in the case of the ActiveRecord adapter) via a call to
|
94
89
|
`Ransack#result`.
|
95
90
|
|
96
|
-
####In your controller
|
91
|
+
#### In your controller
|
97
92
|
|
98
93
|
```ruby
|
99
94
|
def index
|
@@ -114,13 +109,13 @@ def index
|
|
114
109
|
end
|
115
110
|
```
|
116
111
|
|
117
|
-
####In your view
|
112
|
+
#### In your view
|
118
113
|
|
119
114
|
The two primary Ransack view helpers are `search_form_for` and `sort_link`,
|
120
115
|
which are defined in
|
121
116
|
[Ransack::Helpers::FormHelper](lib/ransack/helpers/form_helper.rb).
|
122
117
|
|
123
|
-
####Ransack's `search_form_for` helper replaces `form_for` for creating the view search form
|
118
|
+
#### Ransack's `search_form_for` helper replaces `form_for` for creating the view search form
|
124
119
|
|
125
120
|
```erb
|
126
121
|
<%= search_form_for @q do |f| %>
|
@@ -156,7 +151,7 @@ The `search_form_for` answer format can be set like this:
|
|
156
151
|
<%= search_form_for(@q, format: :json) do |f| %>
|
157
152
|
```
|
158
153
|
|
159
|
-
####Ransack's `sort_link` helper creates table headers that are sortable links
|
154
|
+
#### Ransack's `sort_link` helper creates table headers that are sortable links
|
160
155
|
|
161
156
|
```erb
|
162
157
|
<%= sort_link(@q, :name) %>
|
@@ -205,15 +200,23 @@ This example toggles the sort directions of both fields, by default
|
|
205
200
|
initially sorting the `last_name` field by ascending order, and the
|
206
201
|
`first_name` field by descending order.
|
207
202
|
|
208
|
-
The sort link may be displayed without the order indicator arrow by passing
|
209
|
-
`hide_indicator: true`:
|
210
203
|
|
211
|
-
|
212
|
-
|
204
|
+
The sort link order indicator arrows may be globally customized by setting a
|
205
|
+
`custom_arrows` option in an initializer file like
|
206
|
+
`config/initializers/ransack.rb`:
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
Ransack.configure do |c|
|
210
|
+
c.custom_arrows = {
|
211
|
+
up_arrow: '<i class="custom-up-arrow-icon"></i>',
|
212
|
+
down_arrow: 'U+02193'
|
213
|
+
}
|
214
|
+
end
|
213
215
|
```
|
214
216
|
|
215
|
-
|
216
|
-
by
|
217
|
+
All sort links may be displayed without the order indicator
|
218
|
+
arrows by setting `hide_sort_order_indicators` to true in the initializer file.
|
219
|
+
Note that this hides the arrows even if they were customized:
|
217
220
|
|
218
221
|
```ruby
|
219
222
|
Ransack.configure do |c|
|
@@ -221,7 +224,14 @@ Ransack.configure do |c|
|
|
221
224
|
end
|
222
225
|
```
|
223
226
|
|
224
|
-
|
227
|
+
Without setting it globally, individual sort links may be displayed without
|
228
|
+
the order indicator arrow by passing `hide_indicator: true` in the sort link:
|
229
|
+
|
230
|
+
```erb
|
231
|
+
<%= sort_link(@q, :name, hide_indicator: true) %>
|
232
|
+
```
|
233
|
+
|
234
|
+
#### Ransack's `sort_url` helper is like a `sort_link` but returns only the url
|
225
235
|
|
226
236
|
`sort_url` has the same API as `sort_link`:
|
227
237
|
|
@@ -275,11 +285,12 @@ end
|
|
275
285
|
|
276
286
|
Once you've done so, you can make use of the helpers in [Ransack::Helpers::FormBuilder](lib/ransack/helpers/form_builder.rb) to
|
277
287
|
construct much more complex search forms, such as the one on the
|
278
|
-
[demo
|
288
|
+
[demo app](http://ransack-demo.herokuapp.com/users/advanced_search)
|
289
|
+
(source code [here](https://github.com/activerecord-hackery/ransack_demo)).
|
279
290
|
|
280
291
|
### Ransack #search method
|
281
292
|
|
282
|
-
Ransack will try to
|
293
|
+
Ransack will try to make the class method `#search` available in your
|
283
294
|
models, but if `#search` has already been defined elsewhere, you can always use
|
284
295
|
the default `#ransack` class method. So the following are equivalent:
|
285
296
|
|
@@ -395,13 +406,41 @@ query parameters in your URLs.
|
|
395
406
|
<% end %>
|
396
407
|
```
|
397
408
|
|
409
|
+
### Search Matchers
|
410
|
+
|
411
|
+
List of all possible predicates
|
412
|
+
|
413
|
+
* `*_eq` - equal
|
414
|
+
* `*_not_eq` - not equal
|
415
|
+
* `*_matches` - matches with `LIKE`, e.g. `q[email_matches]=%@gmail.com`
|
416
|
+
* Also: `*_does_not_match`, `*_matches_any`, `*_matches_all`, `*_does_not_match_any`, `*_does_not_match_all`
|
417
|
+
* `*_lt` - less than
|
418
|
+
* `*_lteq` - less than or equal
|
419
|
+
* `*_gt` - greater than
|
420
|
+
* `*_gteq` - greater than or equal
|
421
|
+
* `*_present` - not null and not empty, e.g. `q[name_present]=1` (SQL: `col is not null AND col != ''`)
|
422
|
+
* `*_blank` - is null or empty. (SQL: `col is null OR col = ''`)
|
423
|
+
* `*_null`, `*_not_null` - is null, is not null
|
424
|
+
* `*_in` - match any values in array, e.g. `q[name_in][]=Alice&q[name_in][]=Bob`
|
425
|
+
* `*_not_in` - match none of values in array
|
426
|
+
* `*_lt_any`, `*_lteq_any`, `*_gt_any`, `*_gteq_any` - Compare to list of values, at least positive. (SQL: `col > value1 OR col > value2`)
|
427
|
+
* `*_matches_any`, `*_does_not_match_any` - same as above but with `LIKE`
|
428
|
+
* `*_lt_all`, `*_lteq_all`, `*_gt_all`, `*_gteq_all` - Compare to list of values, all positive. (SQL: `col > value1 AND col > value2`)
|
429
|
+
* `*_matches_all`, `*_does_not_match_all` - same as above but with `LIKE`
|
430
|
+
* `*_not_eq_all` - none of values in a set
|
431
|
+
* `*_start`, `*_not_start`, `*_start_any`, `*_start_all`, `*_not_start_any`, `*_not_start_all` - start with, (SQL: `col LIKE 'value%'`)
|
432
|
+
* `*_end`, `*_not_end`, `*_end_any`, `*_end_all`, `*_not_end_any`, `*_not_end_all` - end with, (SQL: `col LIKE '%value'`)
|
433
|
+
* `*_cont`, `*_cont_any`, `*_cont_all`, `*_not_cont`, `*_not_cont_any`, `*_not_cont_all` - contains value, using `LIKE`
|
434
|
+
* `*_true`, `*_false` - is true and is false
|
435
|
+
|
436
|
+
(See full list: https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/locale/en.yml#L15 and [wiki](https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching))
|
437
|
+
|
398
438
|
### Using Ransackers to add custom search functions via Arel
|
399
439
|
|
400
440
|
The main premise behind Ransack is to provide access to
|
401
441
|
**Arel predicate methods**. Ransack provides special methods, called
|
402
442
|
_ransackers_, for creating additional search functions via Arel. More
|
403
|
-
information about `ransacker` methods can be found [here in the wiki]
|
404
|
-
(https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers).
|
443
|
+
information about `ransacker` methods can be found [here in the wiki](https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers).
|
405
444
|
Feel free to contribute working `ransacker` code examples to the wiki!
|
406
445
|
|
407
446
|
### Problem with DISTINCT selects
|
@@ -511,8 +550,7 @@ for an `auth_object` key in the options hash which can be used by your own
|
|
511
550
|
overridden methods.
|
512
551
|
|
513
552
|
Here is an example that puts all this together, adapted from
|
514
|
-
[this blog post by Ernie Miller]
|
515
|
-
(http://erniemiller.org/2012/05/11/why-your-ruby-class-macros-might-suck-mine-did/).
|
553
|
+
[this blog post by Ernie Miller](http://erniemiller.org/2012/05/11/why-your-ruby-class-macros-might-suck-mine-did/).
|
516
554
|
In an `Article` model, add the following `ransackable_attributes` class method
|
517
555
|
(preferably private):
|
518
556
|
|
@@ -613,7 +651,21 @@ Employee.ransack({ salary_gt: 100_000 }, { auth_object: current_user })
|
|
613
651
|
In Rails 3 and 4, if the `true` value is being passed via url params or some
|
614
652
|
other mechanism that will convert it to a string, the true value may not be
|
615
653
|
passed to the ransackable scope unless you wrap it in an array
|
616
|
-
(i.e. `activated: ['true']`).
|
654
|
+
(i.e. `activated: ['true']`). Ransack will take care of changing 'true' into a
|
655
|
+
boolean. This is currently resolved in Rails 5 :smiley:
|
656
|
+
|
657
|
+
However, perhaps you have `user_id: [1]` and you do not want Ransack to convert
|
658
|
+
1 into a boolean. (Values sanitized to booleans can be found in the
|
659
|
+
[constants.rb](https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/constants.rb#L28)).
|
660
|
+
To turn this off, and handle type conversions yourself, set
|
661
|
+
`sanitize_custom_scope_booleans` to false in an initializer file like
|
662
|
+
config/initializers/ransack.rb:
|
663
|
+
|
664
|
+
```ruby
|
665
|
+
Ransack.configure do |c|
|
666
|
+
c.sanitize_custom_scope_booleans = false
|
667
|
+
end
|
668
|
+
```
|
617
669
|
|
618
670
|
Scopes are a recent addition to Ransack and currently have a few caveats:
|
619
671
|
First, a scope involving child associations needs to be defined in the parent
|
@@ -622,8 +674,7 @@ argument are not easily usable yet, because the array currently needs to be
|
|
622
674
|
wrapped in an array to function (see
|
623
675
|
[this issue](https://github.com/activerecord-hackery/ransack/issues/404)),
|
624
676
|
which is not compatible with Ransack form helpers. For this use case, it may be
|
625
|
-
better for now to use [ransackers]
|
626
|
-
(https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers) instead,
|
677
|
+
better for now to use [ransackers](https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers) instead,
|
627
678
|
where feasible. Pull requests with solutions and tests are welcome!
|
628
679
|
|
629
680
|
### Grouping queries by OR instead of AND
|
@@ -747,9 +798,8 @@ en:
|
|
747
798
|
|
748
799
|
## Mongoid
|
749
800
|
|
750
|
-
Ransack
|
751
|
-
|
752
|
-
[here](http://ransack-mongodb-demo.herokuapp.com/) and the demo source code is
|
801
|
+
Ransack works with Mongoid in the same way as Active Record, except that with
|
802
|
+
Mongoid, associations are not currently supported. Demo source code may be found
|
753
803
|
[here](https://github.com/Zhomart/ransack-mongodb-demo). A `result` method
|
754
804
|
called on a `ransack` search returns a `Mongoid::Criteria` object:
|
755
805
|
|
data/lib/ransack.rb
CHANGED
@@ -7,13 +7,6 @@ Ransack::Adapters.object_mapper.require_constants
|
|
7
7
|
module Ransack
|
8
8
|
extend Configuration
|
9
9
|
class UntraversableAssociationError < StandardError; end;
|
10
|
-
|
11
|
-
SUPPORTS_ATTRIBUTE_ALIAS =
|
12
|
-
begin
|
13
|
-
ActiveRecord::Base.respond_to?(:attribute_aliases)
|
14
|
-
rescue NameError
|
15
|
-
false
|
16
|
-
end
|
17
10
|
end
|
18
11
|
|
19
12
|
Ransack.configure do |config|
|
@@ -1,5 +1,15 @@
|
|
1
1
|
require 'ransack/adapters/active_record/base'
|
2
|
-
|
2
|
+
|
3
|
+
ActiveSupport.on_load(:active_record) do
|
4
|
+
extend Ransack::Adapters::ActiveRecord::Base
|
5
|
+
|
6
|
+
Ransack::SUPPORTS_ATTRIBUTE_ALIAS =
|
7
|
+
begin
|
8
|
+
ActiveRecord::Base.respond_to?(:attribute_aliases)
|
9
|
+
rescue NameError
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
3
13
|
|
4
14
|
require 'ransack/adapters/active_record/context'
|
5
15
|
|
@@ -23,7 +23,8 @@ module Ransack
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def ransack_alias(new_name, old_name)
|
26
|
-
self._ransack_aliases.
|
26
|
+
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
|
27
|
+
old_name.to_s
|
27
28
|
end
|
28
29
|
|
29
30
|
# Ransackable_attributes, by default, returns all column names
|
@@ -7,9 +7,14 @@ module Ransack
|
|
7
7
|
association = attribute.parent
|
8
8
|
if negative? && attribute.associated_collection?
|
9
9
|
query = context.build_correlated_subquery(association)
|
10
|
-
query.where(format_predicate(attribute).not)
|
11
10
|
context.remove_association(association)
|
12
|
-
|
11
|
+
if self.predicate_name == 'not_null' && self.value
|
12
|
+
query.where(format_predicate(attribute))
|
13
|
+
Arel::Nodes::In.new(context.primary_key, Arel.sql(query.to_sql))
|
14
|
+
else
|
15
|
+
query.where(format_predicate(attribute).not)
|
16
|
+
Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql))
|
17
|
+
end
|
13
18
|
else
|
14
19
|
format_predicate(attribute)
|
15
20
|
end
|
@@ -8,6 +8,10 @@ module Ransack
|
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
10
|
included do
|
11
|
+
class_attribute :_ransackers
|
12
|
+
class_attribute :_ransack_aliases
|
13
|
+
self._ransackers ||= {}
|
14
|
+
self._ransack_aliases ||= {}
|
11
15
|
end
|
12
16
|
|
13
17
|
class ColumnWrapper < SimpleDelegator
|
@@ -33,22 +37,6 @@ module Ransack
|
|
33
37
|
end
|
34
38
|
|
35
39
|
module ClassMethods
|
36
|
-
def _ransack_aliases
|
37
|
-
@_ransack_aliases ||= {}
|
38
|
-
end
|
39
|
-
|
40
|
-
def _ransack_aliases=(value)
|
41
|
-
@_ransack_aliases = value
|
42
|
-
end
|
43
|
-
|
44
|
-
def _ransackers
|
45
|
-
@_ransackers ||= {}
|
46
|
-
end
|
47
|
-
|
48
|
-
def _ransackers=(value)
|
49
|
-
@_ransackers = value
|
50
|
-
end
|
51
|
-
|
52
40
|
def ransack(params = {}, options = {})
|
53
41
|
params = params.presence || {}
|
54
42
|
Search.new(self, params ? params.delete_if {
|
@@ -58,7 +46,8 @@ module Ransack
|
|
58
46
|
alias_method :search, :ransack
|
59
47
|
|
60
48
|
def ransack_alias(new_name, old_name)
|
61
|
-
self._ransack_aliases.
|
49
|
+
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
|
50
|
+
old_name.to_s
|
62
51
|
end
|
63
52
|
|
64
53
|
def ransacker(name, opts = {}, &block)
|
@@ -9,7 +9,10 @@ module Ransack
|
|
9
9
|
self.options = {
|
10
10
|
:search_key => :q,
|
11
11
|
:ignore_unknown_conditions => true,
|
12
|
-
:hide_sort_order_indicators => false
|
12
|
+
:hide_sort_order_indicators => false,
|
13
|
+
:up_arrow => '▼'.freeze,
|
14
|
+
:down_arrow => '▲'.freeze,
|
15
|
+
:sanitize_scope_args => true
|
13
16
|
}
|
14
17
|
|
15
18
|
def configure
|
@@ -75,6 +78,43 @@ module Ransack
|
|
75
78
|
self.options[:ignore_unknown_conditions] = boolean
|
76
79
|
end
|
77
80
|
|
81
|
+
# By default, Ransack displays sort order indicator arrows with HTML codes:
|
82
|
+
#
|
83
|
+
# up_arrow: '▼'
|
84
|
+
# down_arrow: '▲'
|
85
|
+
#
|
86
|
+
# One or both defaults may be globally overridden in an initializer file
|
87
|
+
# like `config/initializers/ransack.rb` as follows:
|
88
|
+
#
|
89
|
+
# Ransack.configure do |config|
|
90
|
+
# # Globally set the up arrow to an icon and the down arrow to unicode.
|
91
|
+
# config.custom_arrows = {
|
92
|
+
# up_arrow: '<i class="fa fa-long-arrow-up"></i>',
|
93
|
+
# down_arrow: 'U+02193'
|
94
|
+
# }
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
def custom_arrows=(opts = {})
|
98
|
+
self.options[:up_arrow] = opts[:up_arrow].freeze if opts[:up_arrow]
|
99
|
+
self.options[:down_arrow] = opts[:down_arrow].freeze if opts[:down_arrow]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Ransack sanitizes many values in your custom scopes into booleans.
|
103
|
+
# [1, '1', 't', 'T', 'true', 'TRUE'] all evaluate to true.
|
104
|
+
# [0, '0', 'f', 'F', 'false', 'FALSE'] all evaluate to false.
|
105
|
+
#
|
106
|
+
# This default may be globally overridden in an initializer file like
|
107
|
+
# `config/initializers/ransack.rb` as follows:
|
108
|
+
#
|
109
|
+
# Ransack.configure do |config|
|
110
|
+
# # Accept my custom scope values as what they are.
|
111
|
+
# config.sanitize_custom_scope_booleans = false
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
def sanitize_custom_scope_booleans=(boolean)
|
115
|
+
self.options[:sanitize_scope_args] = boolean
|
116
|
+
end
|
117
|
+
|
78
118
|
# By default, Ransack displays sort order indicator arrows in sort links.
|
79
119
|
# The default may be globally overridden in an initializer file like
|
80
120
|
# `config/initializers/ransack.rb` as follows:
|
data/lib/ransack/search.rb
CHANGED
@@ -123,12 +123,18 @@ module Ransack
|
|
123
123
|
private
|
124
124
|
|
125
125
|
def add_scope(key, args)
|
126
|
+
sanitized_args = if Ransack.options[:sanitize_scope_args]
|
127
|
+
sanitized_scope_args(args)
|
128
|
+
else
|
129
|
+
args
|
130
|
+
end
|
131
|
+
|
126
132
|
if @context.scope_arity(key) == 1
|
127
133
|
@scope_args[key] = args.is_a?(Array) ? args[0] : args
|
128
134
|
else
|
129
|
-
@scope_args[key] = args.is_a?(Array) ?
|
135
|
+
@scope_args[key] = args.is_a?(Array) ? sanitized_args : args
|
130
136
|
end
|
131
|
-
@context.chain_scope(key,
|
137
|
+
@context.chain_scope(key, sanitized_args)
|
132
138
|
end
|
133
139
|
|
134
140
|
def sanitized_scope_args(args)
|
data/lib/ransack/version.rb
CHANGED
@@ -65,6 +65,27 @@ module Ransack
|
|
65
65
|
s = Person.ransack(term_cont: 'nomatch')
|
66
66
|
expect(s.result.to_a).to eq []
|
67
67
|
end
|
68
|
+
|
69
|
+
it 'makes aliases available to subclasses' do
|
70
|
+
yngwie = Musician.create!(name: 'Yngwie Malmsteen')
|
71
|
+
|
72
|
+
musicians = Musician.ransack(term_cont: 'ngw').result
|
73
|
+
expect(musicians).to eq([yngwie])
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'handles naming collisions gracefully' do
|
77
|
+
frank = Person.create!(name: 'Frank Stallone')
|
78
|
+
|
79
|
+
people = Person.ransack(term_cont: 'allon').result
|
80
|
+
expect(people).to eq([frank])
|
81
|
+
|
82
|
+
Class.new(Article) do
|
83
|
+
ransack_alias :term, :title
|
84
|
+
end
|
85
|
+
|
86
|
+
people = Person.ransack(term_cont: 'allon').result
|
87
|
+
expect(people).to eq([frank])
|
88
|
+
end
|
68
89
|
end
|
69
90
|
|
70
91
|
describe '#ransacker' do
|
@@ -274,8 +295,6 @@ module Ransack
|
|
274
295
|
end
|
275
296
|
|
276
297
|
describe '#ransackable_associations' do
|
277
|
-
before { pending "not implemented for mongoid" }
|
278
|
-
|
279
298
|
subject { Person.ransackable_associations }
|
280
299
|
|
281
300
|
it { should include 'parent' }
|
@@ -36,17 +36,73 @@ module Ransack
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'changes default search key parameter' do
|
39
|
-
|
40
|
-
before = Ransack.options.clone
|
39
|
+
default = Ransack.options.clone
|
41
40
|
|
42
|
-
Ransack.configure
|
43
|
-
config.search_key = :query
|
44
|
-
end
|
41
|
+
Ransack.configure { |c| c.search_key = :query }
|
45
42
|
|
46
43
|
expect(Ransack.options[:search_key]).to eq :query
|
47
44
|
|
48
|
-
|
49
|
-
|
45
|
+
Ransack.options = default
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have default values for arrows' do
|
49
|
+
expect(Ransack.options[:up_arrow]).to eq '▼'
|
50
|
+
expect(Ransack.options[:down_arrow]).to eq '▲'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'changes the default value for the up arrow only' do
|
54
|
+
default, new_up_arrow = Ransack.options.clone, 'U+02191'
|
55
|
+
|
56
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: new_up_arrow } }
|
57
|
+
|
58
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
59
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
60
|
+
|
61
|
+
Ransack.options = default
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'changes the default value for the down arrow only' do
|
65
|
+
default, new_down_arrow = Ransack.options.clone, '<i class="down"></i>'
|
66
|
+
|
67
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: new_down_arrow } }
|
68
|
+
|
69
|
+
expect(Ransack.options[:up_arrow]).to eq default[:up_arrow]
|
70
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
71
|
+
|
72
|
+
Ransack.options = default
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'changes the default value for both arrows' do
|
76
|
+
default = Ransack.options.clone
|
77
|
+
new_up_arrow = '<i class="fa fa-long-arrow-up"></i>'
|
78
|
+
new_down_arrow = 'U+02193'
|
79
|
+
|
80
|
+
Ransack.configure do |c|
|
81
|
+
c.custom_arrows = { up_arrow: new_up_arrow, down_arrow: new_down_arrow }
|
82
|
+
end
|
83
|
+
|
84
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
85
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
86
|
+
|
87
|
+
Ransack.options = default
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'consecutive arrow customizations respect previous customizations' do
|
91
|
+
default = Ransack.options.clone
|
92
|
+
|
93
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: 'up' } }
|
94
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
95
|
+
|
96
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'DOWN' } }
|
97
|
+
expect(Ransack.options[:up_arrow]).to eq 'up'
|
98
|
+
|
99
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: '<i>U-Arrow</i>' } }
|
100
|
+
expect(Ransack.options[:down_arrow]).to eq 'DOWN'
|
101
|
+
|
102
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'down arrow-2' } }
|
103
|
+
expect(Ransack.options[:up_arrow]).to eq '<i>U-Arrow</i>'
|
104
|
+
|
105
|
+
Ransack.options = default
|
50
106
|
end
|
51
107
|
|
52
108
|
it 'adds predicates that take arrays, overriding compounds' do
|
@@ -76,8 +132,10 @@ module Ransack
|
|
76
132
|
)
|
77
133
|
end
|
78
134
|
|
79
|
-
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
80
|
-
|
135
|
+
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
136
|
+
.to eq true
|
137
|
+
expect(Ransack.predicates['test_not_in_predicate'].wants_array)
|
138
|
+
.to eq true
|
81
139
|
end
|
82
140
|
|
83
141
|
it 'explicitly does not want array for in/not_in predicates' do
|
@@ -94,8 +152,10 @@ module Ransack
|
|
94
152
|
)
|
95
153
|
end
|
96
154
|
|
97
|
-
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
98
|
-
|
155
|
+
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
156
|
+
.to eq false
|
157
|
+
expect(Ransack.predicates['test_not_in_predicate_no_array'].wants_array)
|
158
|
+
.to eq false
|
99
159
|
end
|
100
160
|
end
|
101
161
|
end
|
data/spec/mongoid/search_spec.rb
CHANGED
@@ -433,7 +433,6 @@ module Ransack
|
|
433
433
|
end
|
434
434
|
|
435
435
|
context 'with joins' do
|
436
|
-
before { pending 'not implemented for mongoid' }
|
437
436
|
it 'allows chaining to access nested conditions' do
|
438
437
|
@s.groupings = [
|
439
438
|
{ :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' }
|
@@ -65,25 +65,31 @@ module Ransack
|
|
65
65
|
expect(s.result.to_sql).to (include 'age > 18')
|
66
66
|
end
|
67
67
|
|
68
|
-
# TODO: Implement a way to pass true/false values like 0 or 1 to
|
69
|
-
# scopes (e.g. with `in` / `not_in` predicates), without Ransack
|
70
|
-
# converting them to true/false boolean values instead.
|
71
|
-
|
72
|
-
# it 'passes true values to scopes', focus: true do
|
73
|
-
# s = Person.ransack('over_age' => 1)
|
74
|
-
# expect(s.result.to_sql).to (include 'age > 1')
|
75
|
-
# end
|
76
|
-
|
77
|
-
# it 'passes false values to scopes', focus: true do
|
78
|
-
# s = Person.ransack('over_age' => 0)
|
79
|
-
# expect(s.result.to_sql).to (include 'age > 0')
|
80
|
-
# end
|
81
|
-
|
82
68
|
it 'chains scopes' do
|
83
69
|
s = Person.ransack('over_age' => 18, 'active' => true)
|
84
70
|
expect(s.result.to_sql).to (include 'age > 18')
|
85
71
|
expect(s.result.to_sql).to (include 'active = 1')
|
86
72
|
end
|
73
|
+
|
74
|
+
context "with sanitize_custom_scope_booleans set to false" do
|
75
|
+
before(:all) do
|
76
|
+
Ransack.configure { |c| c.sanitize_custom_scope_booleans = false }
|
77
|
+
end
|
78
|
+
|
79
|
+
after(:all) do
|
80
|
+
Ransack.configure { |c| c.sanitize_custom_scope_booleans = true }
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'passes true values to scopes' do
|
84
|
+
s = Person.ransack('over_age' => 1)
|
85
|
+
expect(s.result.to_sql).to (include 'age > 1')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'passes false values to scopes' do
|
89
|
+
s = Person.ransack('over_age' => 0)
|
90
|
+
expect(s.result.to_sql).to (include 'age > 0')
|
91
|
+
end
|
92
|
+
end
|
87
93
|
end
|
88
94
|
|
89
95
|
it 'does not raise exception for string :params argument' do
|
@@ -190,6 +196,27 @@ module Ransack
|
|
190
196
|
s = Person.ransack(daddy_eq: 'Drake')
|
191
197
|
expect(s.result.to_a).to eq []
|
192
198
|
end
|
199
|
+
|
200
|
+
it 'makes aliases available to subclasses' do
|
201
|
+
yngwie = Musician.create!(name: 'Yngwie Malmsteen')
|
202
|
+
|
203
|
+
musicians = Musician.ransack(term_cont: 'ngw').result
|
204
|
+
expect(musicians).to eq([yngwie])
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'handles naming collisions gracefully' do
|
208
|
+
frank = Person.create!(name: 'Frank Stallone')
|
209
|
+
|
210
|
+
people = Person.ransack(term_cont: 'allon').result
|
211
|
+
expect(people).to eq([frank])
|
212
|
+
|
213
|
+
Class.new(Article) do
|
214
|
+
ransack_alias :term, :title
|
215
|
+
end
|
216
|
+
|
217
|
+
people = Person.ransack(term_cont: 'allon').result
|
218
|
+
expect(people).to eq([frank])
|
219
|
+
end
|
193
220
|
end
|
194
221
|
|
195
222
|
describe '#ransacker' do
|
@@ -3,9 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Ransack
|
4
4
|
describe Configuration do
|
5
5
|
it 'yields Ransack on configure' do
|
6
|
-
Ransack.configure
|
7
|
-
expect(config).to eq Ransack
|
8
|
-
end
|
6
|
+
Ransack.configure { |config| expect(config).to eq Ransack }
|
9
7
|
end
|
10
8
|
|
11
9
|
it 'adds predicates' do
|
@@ -38,17 +36,73 @@ module Ransack
|
|
38
36
|
end
|
39
37
|
|
40
38
|
it 'changes default search key parameter' do
|
41
|
-
|
42
|
-
before = Ransack.options.clone
|
39
|
+
default = Ransack.options.clone
|
43
40
|
|
44
|
-
Ransack.configure
|
45
|
-
config.search_key = :query
|
46
|
-
end
|
41
|
+
Ransack.configure { |c| c.search_key = :query }
|
47
42
|
|
48
43
|
expect(Ransack.options[:search_key]).to eq :query
|
49
44
|
|
50
|
-
|
51
|
-
|
45
|
+
Ransack.options = default
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have default values for arrows' do
|
49
|
+
expect(Ransack.options[:up_arrow]).to eq '▼'
|
50
|
+
expect(Ransack.options[:down_arrow]).to eq '▲'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'changes the default value for the up arrow only' do
|
54
|
+
default, new_up_arrow = Ransack.options.clone, 'U+02191'
|
55
|
+
|
56
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: new_up_arrow } }
|
57
|
+
|
58
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
59
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
60
|
+
|
61
|
+
Ransack.options = default
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'changes the default value for the down arrow only' do
|
65
|
+
default, new_down_arrow = Ransack.options.clone, '<i class="down"></i>'
|
66
|
+
|
67
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: new_down_arrow } }
|
68
|
+
|
69
|
+
expect(Ransack.options[:up_arrow]).to eq default[:up_arrow]
|
70
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
71
|
+
|
72
|
+
Ransack.options = default
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'changes the default value for both arrows' do
|
76
|
+
default = Ransack.options.clone
|
77
|
+
new_up_arrow = '<i class="fa fa-long-arrow-up"></i>'
|
78
|
+
new_down_arrow = 'U+02193'
|
79
|
+
|
80
|
+
Ransack.configure do |c|
|
81
|
+
c.custom_arrows = { up_arrow: new_up_arrow, down_arrow: new_down_arrow }
|
82
|
+
end
|
83
|
+
|
84
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
85
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
86
|
+
|
87
|
+
Ransack.options = default
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'consecutive arrow customizations respect previous customizations' do
|
91
|
+
default = Ransack.options.clone
|
92
|
+
|
93
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: 'up' } }
|
94
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
95
|
+
|
96
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'DOWN' } }
|
97
|
+
expect(Ransack.options[:up_arrow]).to eq 'up'
|
98
|
+
|
99
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: '<i>U-Arrow</i>' } }
|
100
|
+
expect(Ransack.options[:down_arrow]).to eq 'DOWN'
|
101
|
+
|
102
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'down arrow-2' } }
|
103
|
+
expect(Ransack.options[:up_arrow]).to eq '<i>U-Arrow</i>'
|
104
|
+
|
105
|
+
Ransack.options = default
|
52
106
|
end
|
53
107
|
|
54
108
|
it 'adds predicates that take arrays, overriding compounds' do
|
@@ -78,8 +132,10 @@ module Ransack
|
|
78
132
|
)
|
79
133
|
end
|
80
134
|
|
81
|
-
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
82
|
-
|
135
|
+
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
136
|
+
.to eq true
|
137
|
+
expect(Ransack.predicates['test_not_in_predicate'].wants_array)
|
138
|
+
.to eq true
|
83
139
|
end
|
84
140
|
|
85
141
|
it 'explicitly does not want array for in/not_in predicates' do
|
@@ -96,8 +152,10 @@ module Ransack
|
|
96
152
|
)
|
97
153
|
end
|
98
154
|
|
99
|
-
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
100
|
-
|
155
|
+
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
156
|
+
.to eq false
|
157
|
+
expect(Ransack.predicates['test_not_in_predicate_no_array'].wants_array)
|
158
|
+
.to eq false
|
101
159
|
end
|
102
160
|
end
|
103
161
|
end
|
@@ -649,10 +649,57 @@ module Ransack
|
|
649
649
|
it { should match /Full Name ▼/ }
|
650
650
|
end
|
651
651
|
|
652
|
-
describe '#sort_link with config set
|
652
|
+
describe '#sort_link with config set with custom up_arrow' do
|
653
|
+
before do
|
654
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: "\u{1F446}" } }
|
655
|
+
end
|
656
|
+
|
657
|
+
after do
|
658
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: "▼" } }
|
659
|
+
end
|
660
|
+
|
661
|
+
subject { @controller.view_context
|
662
|
+
.sort_link(
|
663
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
664
|
+
:name,
|
665
|
+
controller: 'people',
|
666
|
+
hide_indicator: false
|
667
|
+
)
|
668
|
+
}
|
669
|
+
|
670
|
+
it { should match /Full Name \u{1F446}/ }
|
671
|
+
end
|
672
|
+
|
673
|
+
describe '#sort_link with config set with custom down_arrow' do
|
674
|
+
before do
|
675
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: "\u{1F447}" } }
|
676
|
+
end
|
677
|
+
|
678
|
+
after do
|
679
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: "▲" } }
|
680
|
+
end
|
681
|
+
|
682
|
+
subject { @controller.view_context
|
683
|
+
.sort_link(
|
684
|
+
[:main_app, Person.search(sorts: ['name asc'])],
|
685
|
+
:name,
|
686
|
+
controller: 'people',
|
687
|
+
hide_indicator: false
|
688
|
+
)
|
689
|
+
}
|
690
|
+
|
691
|
+
it { should match /Full Name \u{1F447}/ }
|
692
|
+
end
|
693
|
+
|
694
|
+
describe '#sort_link with config set to hide arrows' do
|
653
695
|
before do
|
654
696
|
Ransack.configure { |c| c.hide_sort_order_indicators = true }
|
655
697
|
end
|
698
|
+
|
699
|
+
after do
|
700
|
+
Ransack.configure { |c| c.hide_sort_order_indicators = false }
|
701
|
+
end
|
702
|
+
|
656
703
|
subject { @controller.view_context
|
657
704
|
.sort_link(
|
658
705
|
[:main_app, Person.search(sorts: ['name desc'])],
|
@@ -660,13 +707,15 @@ module Ransack
|
|
660
707
|
controller: 'people'
|
661
708
|
)
|
662
709
|
}
|
710
|
+
|
663
711
|
it { should_not match /▼|▲/ }
|
664
712
|
end
|
665
713
|
|
666
|
-
describe '#sort_link with config set to
|
714
|
+
describe '#sort_link with config set to show arrows (default setting)' do
|
667
715
|
before do
|
668
716
|
Ransack.configure { |c| c.hide_sort_order_indicators = false }
|
669
717
|
end
|
718
|
+
|
670
719
|
subject { @controller.view_context
|
671
720
|
.sort_link(
|
672
721
|
[:main_app, Person.search(sorts: ['name desc'])],
|
@@ -674,9 +723,62 @@ module Ransack
|
|
674
723
|
controller: 'people'
|
675
724
|
)
|
676
725
|
}
|
726
|
+
|
677
727
|
it { should match /Full Name ▼/ }
|
678
728
|
end
|
679
729
|
|
730
|
+
describe '#sort_link w/config to hide arrows + custom arrow, hides all' do
|
731
|
+
before do
|
732
|
+
Ransack.configure do |c|
|
733
|
+
c.hide_sort_order_indicators = true
|
734
|
+
c.custom_arrows = { down_arrow: 'down' }
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
after do
|
739
|
+
Ransack.configure do |c|
|
740
|
+
c.hide_sort_order_indicators = false
|
741
|
+
c.custom_arrows = { down_arrow: '▲' }
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
subject { @controller.view_context
|
746
|
+
.sort_link(
|
747
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
748
|
+
:name,
|
749
|
+
controller: 'people'
|
750
|
+
)
|
751
|
+
}
|
752
|
+
|
753
|
+
it { should_not match /▼|down/ }
|
754
|
+
end
|
755
|
+
|
756
|
+
describe '#sort_link with config set to show arrows + custom arrow' do
|
757
|
+
before do
|
758
|
+
Ransack.configure do |c|
|
759
|
+
c.hide_sort_order_indicators = false
|
760
|
+
c.custom_arrows = { up_arrow: 'up-value' }
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
after do
|
765
|
+
Ransack.configure do |c|
|
766
|
+
c.hide_sort_order_indicators = false
|
767
|
+
c.custom_arrows = { up_arrow: '▼' }
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
subject { @controller.view_context
|
772
|
+
.sort_link(
|
773
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
774
|
+
:name,
|
775
|
+
controller: 'people'
|
776
|
+
)
|
777
|
+
}
|
778
|
+
|
779
|
+
it { should match /▲|up-value/ }
|
780
|
+
end
|
781
|
+
|
680
782
|
describe '#sort_link with a block' do
|
681
783
|
subject { @controller.view_context
|
682
784
|
.sort_link(
|
@@ -329,6 +329,28 @@ module Ransack
|
|
329
329
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
330
330
|
expect(@s.result.to_sql).to match /#{field} IS NULL/
|
331
331
|
end
|
332
|
+
|
333
|
+
describe 'with association qeury' do
|
334
|
+
it 'generates a value IS NOT NULL query' do
|
335
|
+
@s.comments_id_not_null = true
|
336
|
+
sql = @s.result.to_sql
|
337
|
+
parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
|
338
|
+
expect(sql).to match /#{parent_field} IN/
|
339
|
+
field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
|
340
|
+
expect(sql).to match /#{field} IS NOT NULL/
|
341
|
+
expect(sql).not_to match /AND NOT/
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'generates a value IS NULL query when assigned false' do
|
345
|
+
@s.comments_id_not_null = false
|
346
|
+
sql = @s.result.to_sql
|
347
|
+
parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
|
348
|
+
expect(sql).to match /#{parent_field} NOT IN/
|
349
|
+
field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
|
350
|
+
expect(sql).to match /#{field} IS NULL/
|
351
|
+
expect(sql).to match /AND NOT/
|
352
|
+
end
|
353
|
+
end
|
332
354
|
end
|
333
355
|
|
334
356
|
describe 'present' do
|
data/spec/support/schema.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ransack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ernie Miller
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2017-06-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionpack
|
@@ -317,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
317
|
version: '0'
|
318
318
|
requirements: []
|
319
319
|
rubyforge_project: ransack
|
320
|
-
rubygems_version: 2.
|
320
|
+
rubygems_version: 2.5.2
|
321
321
|
signing_key:
|
322
322
|
specification_version: 4
|
323
323
|
summary: Object-based searching for Active Record and Mongoid (currently).
|