ransack 1.4.1 → 1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/CONTRIBUTING.md +7 -7
- data/Gemfile +7 -0
- data/README.md +139 -34
- data/lib/ransack/adapters/active_record/3.0/compat.rb +5 -5
- data/lib/ransack/adapters/active_record/3.0/context.rb +32 -16
- data/lib/ransack/adapters/active_record/3.1/context.rb +31 -16
- data/lib/ransack/adapters/active_record/context.rb +34 -26
- data/lib/ransack/configuration.rb +1 -1
- data/lib/ransack/constants.rb +72 -37
- data/lib/ransack/context.rb +18 -12
- data/lib/ransack/helpers/form_builder.rb +32 -15
- data/lib/ransack/helpers/form_helper.rb +83 -55
- data/lib/ransack/naming.rb +1 -1
- data/lib/ransack/nodes/condition.rb +9 -9
- data/lib/ransack/nodes/grouping.rb +15 -9
- data/lib/ransack/nodes/sort.rb +9 -4
- data/lib/ransack/predicate.rb +10 -10
- data/lib/ransack/search.rb +15 -8
- data/lib/ransack/translate.rb +9 -6
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +8 -2
- data/spec/ransack/adapters/active_record/base_spec.rb +2 -2
- data/spec/ransack/helpers/form_builder_spec.rb +63 -43
- data/spec/ransack/helpers/form_helper_spec.rb +163 -2
- data/spec/ransack/nodes/grouping_spec.rb +44 -1
- data/spec/ransack/predicate_spec.rb +165 -3
- data/spec/ransack/translate_spec.rb +4 -1
- data/spec/support/en.yml +5 -0
- data/spec/support/schema.rb +6 -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: d33a76673ff5b03a95d1b2ea72c5fcc552fc24a3
|
4
|
+
data.tar.gz: 061c963998e43b654a28e0b3e7e9501feee14192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa17a37043b1924961e17631865374576b78584068785c91331c06567b285ce10764b837c78f54f740570696e2ffd620e6681a391600074f2cc33d5d73956a1c
|
7
|
+
data.tar.gz: 7f3253f6d31f941546e0244389dcff4be6ec55e90511954c0eb0151447a27051b2c98a2d1b8e57ed89c279e98c1c608c5ee24a56115f8095aeed2038130ff7cb
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,81 @@
|
|
2
2
|
This change log was started in August 2014. All notable changes to this project
|
3
3
|
henceforth should be documented here.
|
4
4
|
|
5
|
+
## Version 1.5.0 - 2014-10-26
|
6
|
+
### Added
|
7
|
+
|
8
|
+
* Add support for multiple sort fields and default orders in Ransack
|
9
|
+
`sort_link` helpers
|
10
|
+
([pull request](https://github.com/activerecord-hackery/ransack/pull/438)).
|
11
|
+
|
12
|
+
*Caleb Land*, *James u007*
|
13
|
+
|
14
|
+
* Add tests for `lteq`, `lt`, `gteq` and `gt` predicates. They are also
|
15
|
+
tested in Arel, but testing them in Ransack has proven useful to detect
|
16
|
+
issues.
|
17
|
+
|
18
|
+
*Jon Atack*
|
19
|
+
|
20
|
+
* Add tests for unknown attribute names.
|
21
|
+
|
22
|
+
*Joe Yates*
|
23
|
+
|
24
|
+
* Add tests for attribute names containing '_or_' and '_and_'.
|
25
|
+
|
26
|
+
*Joe Yates*, *Jon Atack*
|
27
|
+
|
28
|
+
* Add tests for attribute names ending with '_start' and '_end'.
|
29
|
+
|
30
|
+
*Jon Atack*, *Timo Schilling*
|
31
|
+
|
32
|
+
* Add tests for `start`, `not_start`, `end` and `not_end` predicates, with
|
33
|
+
emphasis on cases when attribute names end with `_start` and `_end`.
|
34
|
+
|
35
|
+
*Jon Atack*
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
|
39
|
+
* Fix a regression where form labels for attributes through a `belongs_to`
|
40
|
+
association without a translation for the attribute in the locales file
|
41
|
+
would cause a "no implicit conversion of nil into Hash" crash instead of
|
42
|
+
falling back on the attribute name. Added test coverage.
|
43
|
+
|
44
|
+
*John Dell*, *Jon Atack*, *jasdeepgosal*
|
45
|
+
|
46
|
+
* Fix the `form_helper date_select` spec that was failing with Rails 4.2 and
|
47
|
+
master.
|
48
|
+
|
49
|
+
*Jon Atack*
|
50
|
+
|
51
|
+
* Improve `attribute_method?` parsing for method names containing `_and_` and
|
52
|
+
`_or_`. Attributes named like `foo_and_bar` or `foo_or_bar` are recognized
|
53
|
+
now instead of running failing checks for `foo` and `bar`.
|
54
|
+
|
55
|
+
*Joe Yates*
|
56
|
+
|
57
|
+
* Improve `attribute_method?` parsing for method names ending with a
|
58
|
+
predicate like `_start` and `_end`. For instance, a `life_start` attribute
|
59
|
+
is now recognized instead of raising a NoMethodError.
|
60
|
+
|
61
|
+
*Timo Schilling*, *Jon Atack*
|
62
|
+
|
63
|
+
### Changed
|
64
|
+
|
65
|
+
* Reduce object allocations and memory footprint (with a slight speed gain as
|
66
|
+
well) by extracting commonly used strings into top level constants and
|
67
|
+
replacing calls to `#try` methods with simple nil checking.
|
68
|
+
|
69
|
+
*Jon Atack*
|
70
|
+
|
71
|
+
|
72
|
+
## Version 1.4.1 - 2014-09-23
|
73
|
+
### Fixed
|
74
|
+
|
75
|
+
* Fix README markdown so RubyGems documentation picks up the formatting correctly.
|
76
|
+
|
77
|
+
*Jon Atack*
|
78
|
+
|
79
|
+
|
5
80
|
## Version 1.4.0 - 2014-09-23
|
6
81
|
### Added
|
7
82
|
|
data/CONTRIBUTING.md
CHANGED
@@ -4,8 +4,8 @@ Ransack is an open source project and we encourage contributions.
|
|
4
4
|
|
5
5
|
When filing an issue on the Ransack project, please provide these details:
|
6
6
|
|
7
|
-
* A comprehensive list of steps to reproduce the issue
|
8
|
-
* The version of Ransack *and* the
|
7
|
+
* A comprehensive list of steps to reproduce the issue, or, _far better_, a failing spec!
|
8
|
+
* The version (and branch) of Ransack *and* the versions of Rails and Ruby.
|
9
9
|
* Any relevant stack traces ("Full trace" preferred).
|
10
10
|
|
11
11
|
In 99% of cases, this information is enough to determine the cause and
|
@@ -53,17 +53,17 @@ day). We may suggest some changes or improvements or alternatives.
|
|
53
53
|
Some things that will increase the chance that your pull request is accepted,
|
54
54
|
taken straight from the Ruby on Rails guide:
|
55
55
|
|
56
|
-
* Use Rails idioms and helpers
|
57
|
-
* Include tests that fail without your code, and pass with it
|
58
|
-
* Update the
|
59
|
-
|
56
|
+
* Use Rails idioms and helpers.
|
57
|
+
* Include tests that fail without your code, and pass with it.
|
58
|
+
* Update the README, the change log, the wiki documentation... anything that is
|
59
|
+
affected by your contribution.
|
60
60
|
|
61
61
|
Syntax:
|
62
62
|
|
63
63
|
* Two spaces, no tabs.
|
64
64
|
* 80 characters per line.
|
65
65
|
* No trailing whitespace. Blank lines should not have any space.
|
66
|
-
* Prefer
|
66
|
+
* Prefer `&&`/`||` over `and`/`or`.
|
67
67
|
* `MyClass.my_method(my_arg)` not `my_method( my_arg )` or my_method my_arg.
|
68
68
|
* `a = b` and not `a=b`.
|
69
69
|
* `a_method { |block| ... }` and not `a_method { | block | ... }` or
|
data/Gemfile
CHANGED
@@ -5,8 +5,15 @@ gem 'rake'
|
|
5
5
|
|
6
6
|
rails = ENV['RAILS'] || 'master'
|
7
7
|
|
8
|
+
if rails[0,3] == '4.2' || rails == 'master'
|
9
|
+
gem 'arel', github: 'rails/arel', branch: 'master'
|
10
|
+
end
|
11
|
+
|
8
12
|
gem 'polyamorous', '~> 1.1'
|
9
13
|
|
14
|
+
# Provide timezone information on Windows
|
15
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
|
16
|
+
|
10
17
|
case rails
|
11
18
|
when /\// # A path
|
12
19
|
gem 'activesupport', path: "#{rails}/activesupport"
|
data/README.md
CHANGED
@@ -42,12 +42,18 @@ gem 'ransack', github: 'activerecord-hackery/ransack'
|
|
42
42
|
|
43
43
|
The other branches (`rails-4`, `rails-4.1`, and `rails-4.2`) were each used for
|
44
44
|
developing and running Ransack with the latest upcoming version of Rails at the
|
45
|
-
time. They are
|
45
|
+
time. They are smaller and possibly slightly faster because they do not have to
|
46
46
|
support previous versions of Rails and Active Record. Once support for that
|
47
47
|
Rails version is merged from the branch into Ransack master, the branch is no
|
48
48
|
longer actively maintained -- unless the open source community submits pull
|
49
49
|
requests to maintain them. You are welcome to do so!
|
50
50
|
|
51
|
+
To use one of the branches, for example the `rails-4.1` branch:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
gem 'ransack', github: 'activerecord-hackery/ransack', branch: 'rails-4.1'
|
55
|
+
```
|
56
|
+
|
51
57
|
## Usage
|
52
58
|
|
53
59
|
Ransack can be used in one of two modes, simple or advanced.
|
@@ -110,7 +116,7 @@ The two primary Ransack view helpers are `search_form_for` and `sort_link`,
|
|
110
116
|
which are defined in
|
111
117
|
[Ransack::Helpers::FormHelper](lib/ransack/helpers/form_helper.rb).
|
112
118
|
|
113
|
-
#####
|
119
|
+
#####Ransack's `search_form_for` helper replaces `form_for` for creating the view search form:
|
114
120
|
|
115
121
|
```erb
|
116
122
|
<%= search_form_for @q do |f| %>
|
@@ -145,18 +151,39 @@ The `search_form_for` answer format can be set like this:
|
|
145
151
|
<%= search_form_for(@q, format: :json) do |f| %>
|
146
152
|
```
|
147
153
|
|
148
|
-
#####
|
154
|
+
#####Ransack's `sort_link` helper creates table headers that are sortable links:
|
149
155
|
|
150
156
|
```erb
|
151
|
-
<%=
|
157
|
+
<%= sort_link(@q, :name) %>
|
152
158
|
```
|
153
159
|
Additional options can be passed after the column attribute, like a different
|
154
160
|
column title or a default sort order:
|
155
161
|
|
156
162
|
```erb
|
157
|
-
<%=
|
163
|
+
<%= sort_link(@q, :name, 'Last Name', default_order: :desc) %>
|
158
164
|
```
|
159
165
|
|
166
|
+
You can also sort on multiple fields by specifying an ordered array:
|
167
|
+
|
168
|
+
```erb
|
169
|
+
<%= sort_link(@q, :last_name, [:last_name, 'first_name asc'], 'Last Name') %>
|
170
|
+
```
|
171
|
+
|
172
|
+
In the example above, clicking the link will sort by `last_name` and then
|
173
|
+
`first_name`. Specifying the sort direction on a field in the array tells
|
174
|
+
Ransack to _always_ sort that particular field in the specified direction.
|
175
|
+
|
176
|
+
Multiple `default_order` fields may also be specified with a hash:
|
177
|
+
|
178
|
+
```erb
|
179
|
+
<%= sort_link(@q, :last_name, %i(last_name first_name),
|
180
|
+
default_order: { last_name: 'asc', first_name: 'desc' }) %>
|
181
|
+
```
|
182
|
+
|
183
|
+
This example toggles the sort directions of both fields, by default
|
184
|
+
initially sorting the `last_name` field by ascending order, and the
|
185
|
+
`first_name` field by descending order.
|
186
|
+
|
160
187
|
### Advanced Mode
|
161
188
|
|
162
189
|
"Advanced" searches (ab)use Rails' nested attributes functionality in order to
|
@@ -291,29 +318,37 @@ class methods in your models to apply selective authorization:
|
|
291
318
|
Here is how these four methods are implemented in Ransack:
|
292
319
|
|
293
320
|
```ruby
|
294
|
-
|
295
|
-
#
|
296
|
-
#
|
297
|
-
|
298
|
-
|
321
|
+
# Ransackable_attributes, by default, returns all column names
|
322
|
+
# and any defined ransackers as an array of strings.
|
323
|
+
# For overriding with a whitelist array of strings.
|
324
|
+
#
|
325
|
+
def ransackable_attributes(auth_object = nil)
|
326
|
+
column_names + _ransackers.keys
|
327
|
+
end
|
299
328
|
|
300
|
-
|
301
|
-
#
|
329
|
+
# Ransackable_associations, by default, returns the names
|
330
|
+
# of all associations as an array of strings.
|
302
331
|
# For overriding with a whitelist array of strings.
|
303
|
-
|
304
|
-
|
332
|
+
#
|
333
|
+
def ransackable_associations(auth_object = nil)
|
334
|
+
reflect_on_all_associations.map { |a| a.name.to_s }
|
335
|
+
end
|
305
336
|
|
306
|
-
|
307
|
-
#
|
308
|
-
#
|
309
|
-
|
310
|
-
|
337
|
+
# Ransortable_attributes, by default, returns the names
|
338
|
+
# of all attributes available for sorting as an array of strings.
|
339
|
+
# For overriding with a whitelist array of strings.
|
340
|
+
#
|
341
|
+
def ransortable_attributes(auth_object = nil)
|
342
|
+
ransackable_attributes(auth_object)
|
343
|
+
end
|
311
344
|
|
312
|
-
|
313
|
-
#
|
314
|
-
#
|
315
|
-
|
316
|
-
|
345
|
+
# Ransackable_scopes, by default, returns an empty array
|
346
|
+
# i.e. no class methods/scopes are authorized.
|
347
|
+
# For overriding with a whitelist array of *symbols*.
|
348
|
+
#
|
349
|
+
def ransackable_scopes(auth_object = nil)
|
350
|
+
[]
|
351
|
+
end
|
317
352
|
```
|
318
353
|
|
319
354
|
Any values not returned from these methods will be ignored by Ransack, i.e.
|
@@ -329,6 +364,7 @@ Here is an example that puts all this together, adapted from
|
|
329
364
|
(http://erniemiller.org/2012/05/11/why-your-ruby-class-macros-might-suck-mine-did/).
|
330
365
|
In an `Article` model, add the following `ransackable_attributes` class method
|
331
366
|
(preferably private):
|
367
|
+
|
332
368
|
```ruby
|
333
369
|
class Article < ActiveRecord::Base
|
334
370
|
|
@@ -345,7 +381,9 @@ class Article < ActiveRecord::Base
|
|
345
381
|
end
|
346
382
|
end
|
347
383
|
```
|
384
|
+
|
348
385
|
Here is example code for the `articles_controller`:
|
386
|
+
|
349
387
|
```ruby
|
350
388
|
class ArticlesController < ApplicationController
|
351
389
|
|
@@ -361,7 +399,9 @@ class ArticlesController < ApplicationController
|
|
361
399
|
end
|
362
400
|
end
|
363
401
|
```
|
402
|
+
|
364
403
|
Trying it out in `rails console`:
|
404
|
+
|
365
405
|
```ruby
|
366
406
|
> Article
|
367
407
|
=> Article(id: integer, person_id: integer, title: string, body: text)
|
@@ -381,6 +421,7 @@ Trying it out in `rails console`:
|
|
381
421
|
> Article.search({ id_eq: 1 }, { auth_object: :admin }).result.to_sql
|
382
422
|
=> SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1
|
383
423
|
```
|
424
|
+
|
384
425
|
That's it! Now you know how to whitelist/blacklist various elements in Ransack.
|
385
426
|
|
386
427
|
### Using Scopes/Class Methods
|
@@ -393,7 +434,7 @@ scope accepts a value:
|
|
393
434
|
|
394
435
|
```ruby
|
395
436
|
class Employee < ActiveRecord::Base
|
396
|
-
scope :active, ->(boolean = true) { (
|
437
|
+
scope :active, ->(boolean = true) { where(active: boolean) }
|
397
438
|
scope :salary_gt, ->(amount) { where('salary > ?', amount) }
|
398
439
|
|
399
440
|
# Scopes are just syntactical sugar for class methods, which may also be used:
|
@@ -420,6 +461,19 @@ Employee.search({ active: true, hired_since: '2013-01-01' })
|
|
420
461
|
Employee.search({ salary_gt: 100_000 }, { auth_object: current_user })
|
421
462
|
```
|
422
463
|
|
464
|
+
Scopes are a recent addition to Ransack and currently have a few caveats:
|
465
|
+
First, a scope involving child associations needs to be defined in the parent
|
466
|
+
table model, not in the child model. Second, scopes with an array as an
|
467
|
+
argument are not easily usable yet, because the array currently needs to be
|
468
|
+
wrapped in an array to function (see
|
469
|
+
[this issue](https://github.com/activerecord-hackery/ransack/issues/404)),
|
470
|
+
which is not compatible with Ransack form helpers. For this use case, it may be
|
471
|
+
better for now to use [ransackers]
|
472
|
+
(https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers) instead
|
473
|
+
where feasible. Finally, there is also
|
474
|
+
[this issue](https://github.com/activerecord-hackery/ransack/issues/403)
|
475
|
+
to be aware of. Pull requests with solutions and tests are welcome!
|
476
|
+
|
423
477
|
### Grouping queries by OR instead of AND
|
424
478
|
|
425
479
|
The default `AND` grouping can be changed to `OR` by adding `m: 'or'` to the
|
@@ -479,16 +533,14 @@ artists.result.to_sql
|
|
479
533
|
|
480
534
|
### Using SimpleForm
|
481
535
|
|
482
|
-
If you
|
483
|
-
RANSACK_FORM_BUILDER environment variable before Rails
|
484
|
-
|
485
|
-
|
536
|
+
If you would like to combine the Ransack and SimpleForm form builders, set the
|
537
|
+
`RANSACK_FORM_BUILDER` environment variable before Rails boots up, e.g. in
|
538
|
+
`config/application.rb` before `require 'rails/all'` as shown below (and add
|
539
|
+
`gem 'simple_form'` in your Gemfile).
|
486
540
|
|
487
541
|
```ruby
|
488
542
|
require File.expand_path('../boot', __FILE__)
|
489
|
-
|
490
543
|
ENV['RANSACK_FORM_BUILDER'] = '::SimpleForm::FormBuilder'
|
491
|
-
|
492
544
|
require 'rails/all'
|
493
545
|
```
|
494
546
|
|
@@ -499,14 +551,67 @@ Ransack translation files are available in
|
|
499
551
|
many translations for Ransack available at
|
500
552
|
http://www.localeapp.com/projects/2999.
|
501
553
|
|
554
|
+
Predicate and attribute translations in forms may be specified as follows (see
|
555
|
+
the translation files in [Ransack::Locale](lib/ransack/locale) for more examples):
|
556
|
+
|
557
|
+
locales/en.yml:
|
558
|
+
```yml
|
559
|
+
en:
|
560
|
+
ransack:
|
561
|
+
asc: ascending
|
562
|
+
desc: descending
|
563
|
+
predicates:
|
564
|
+
cont: contains
|
565
|
+
not_cont: not contains
|
566
|
+
start: starts with
|
567
|
+
end: ends with
|
568
|
+
gt: greater than
|
569
|
+
lt: less than
|
570
|
+
attributes:
|
571
|
+
person:
|
572
|
+
name: Full Name
|
573
|
+
article:
|
574
|
+
title: Article Title
|
575
|
+
body: Main Content
|
576
|
+
```
|
577
|
+
|
578
|
+
Attribute names may also be changed globally, or under `activerecord`:
|
579
|
+
|
580
|
+
```yml
|
581
|
+
en:
|
582
|
+
attributes:
|
583
|
+
model_name:
|
584
|
+
model_field1: field name1
|
585
|
+
model_field2: field name2
|
586
|
+
activerecord:
|
587
|
+
attributes:
|
588
|
+
namespace/article:
|
589
|
+
title: AR Namespaced Title
|
590
|
+
namespace_article:
|
591
|
+
title: Old Ransack Namespaced Title
|
592
|
+
```
|
593
|
+
|
594
|
+
## Semantic Versioning
|
595
|
+
|
596
|
+
Ransack attempts to follow semantic versioning in the format of `x.y.z`, where:
|
597
|
+
|
598
|
+
`x` stands for a major version (new features that are not backward-compatible).
|
599
|
+
`y` stands for a minor version (new features that are backward-compatible).
|
600
|
+
`z` stands for a patch (bug fixes).
|
601
|
+
|
602
|
+
In other words: `Major.Minor.Patch`.
|
603
|
+
|
502
604
|
## Contributions
|
503
605
|
|
504
606
|
To support the project:
|
505
607
|
|
506
608
|
* Use Ransack in your apps, and let us know if you encounter anything that's
|
507
|
-
broken or missing. A failing spec is awesome. A pull
|
508
|
-
|
509
|
-
|
609
|
+
broken or missing. A failing spec to demonstrate the issue is awesome. A pull
|
610
|
+
request with passing tests is even better!
|
611
|
+
* Before filing an issue or pull request, be sure to read and follow the
|
612
|
+
[Contributing Guide](CONTRIBUTING.md).
|
613
|
+
* Please use Stack Overflow or other sites for questions or discussion not
|
614
|
+
directly related to bug reports, pull requests, or documentation improvements.
|
510
615
|
* Spread the word on Twitter, Facebook, and elsewhere if Ransack's been useful
|
511
616
|
to you. The more people who are using the project, the quicker we can find and
|
512
617
|
fix bugs!
|
@@ -135,16 +135,16 @@ module Arel
|
|
135
135
|
"#{
|
136
136
|
o.name
|
137
137
|
}(#{
|
138
|
-
o.distinct ?
|
138
|
+
o.distinct ? Ransack::Constants::DISTINCT : Ransack::Constants::EMPTY
|
139
139
|
}#{
|
140
|
-
o.expressions.map { |x| visit x }.join(
|
140
|
+
o.expressions.map { |x| visit x }.join(Ransack::Constants::COMMA_SPACE)
|
141
141
|
})#{
|
142
|
-
o.alias ? " AS #{visit o.alias}" :
|
142
|
+
o.alias ? " AS #{visit o.alias}" : Ransack::Constants::EMPTY
|
143
143
|
}"
|
144
144
|
end
|
145
145
|
|
146
146
|
def visit_Arel_Nodes_And o
|
147
|
-
o.children.map { |x| visit x }.join
|
147
|
+
o.children.map { |x| visit x }.join(' AND '.freeze)
|
148
148
|
end
|
149
149
|
|
150
150
|
def visit_Arel_Nodes_Not o
|
@@ -161,7 +161,7 @@ module Arel
|
|
161
161
|
quote(value, attr && column_for(attr))
|
162
162
|
end
|
163
163
|
}
|
164
|
-
.join
|
164
|
+
.join(Ransack::Constants::COMMA_SPACE)
|
165
165
|
})"
|
166
166
|
end
|
167
167
|
end
|