ransack 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +47 -3
  3. data/CHANGELOG.md +106 -18
  4. data/CONTRIBUTING.md +56 -23
  5. data/Gemfile +16 -5
  6. data/README.md +114 -38
  7. data/Rakefile +30 -2
  8. data/lib/ransack.rb +9 -0
  9. data/lib/ransack/adapters/active_record/3.0/compat.rb +11 -8
  10. data/lib/ransack/adapters/active_record/3.0/context.rb +14 -22
  11. data/lib/ransack/adapters/active_record/3.1/context.rb +14 -22
  12. data/lib/ransack/adapters/active_record/context.rb +36 -31
  13. data/lib/ransack/adapters/active_record/ransack/constants.rb +113 -0
  14. data/lib/ransack/adapters/active_record/ransack/context.rb +64 -0
  15. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +48 -0
  16. data/lib/ransack/adapters/active_record/ransack/translate.rb +12 -0
  17. data/lib/ransack/adapters/active_record/ransack/visitor.rb +24 -0
  18. data/lib/ransack/adapters/mongoid.rb +13 -0
  19. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  20. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +37 -0
  21. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +17 -0
  22. data/lib/ransack/adapters/mongoid/attributes/predications.rb +141 -0
  23. data/lib/ransack/adapters/mongoid/base.rb +126 -0
  24. data/lib/ransack/adapters/mongoid/context.rb +208 -0
  25. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +23 -0
  26. data/lib/ransack/adapters/mongoid/ransack/constants.rb +88 -0
  27. data/lib/ransack/adapters/mongoid/ransack/context.rb +60 -0
  28. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +27 -0
  29. data/lib/ransack/adapters/mongoid/ransack/translate.rb +13 -0
  30. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +24 -0
  31. data/lib/ransack/adapters/mongoid/table.rb +35 -0
  32. data/lib/ransack/configuration.rb +22 -4
  33. data/lib/ransack/constants.rb +26 -120
  34. data/lib/ransack/context.rb +32 -60
  35. data/lib/ransack/helpers/form_builder.rb +50 -36
  36. data/lib/ransack/helpers/form_helper.rb +148 -104
  37. data/lib/ransack/naming.rb +11 -11
  38. data/lib/ransack/nodes.rb +2 -0
  39. data/lib/ransack/nodes/bindable.rb +12 -4
  40. data/lib/ransack/nodes/condition.rb +5 -22
  41. data/lib/ransack/nodes/grouping.rb +9 -10
  42. data/lib/ransack/nodes/sort.rb +3 -2
  43. data/lib/ransack/nodes/value.rb +1 -2
  44. data/lib/ransack/predicate.rb +3 -3
  45. data/lib/ransack/search.rb +46 -13
  46. data/lib/ransack/translate.rb +8 -8
  47. data/lib/ransack/version.rb +1 -1
  48. data/lib/ransack/visitor.rb +4 -16
  49. data/ransack.gemspec +1 -0
  50. data/spec/mongoid/adapters/mongoid/base_spec.rb +276 -0
  51. data/spec/mongoid/adapters/mongoid/context_spec.rb +56 -0
  52. data/spec/mongoid/configuration_spec.rb +66 -0
  53. data/spec/mongoid/dependencies_spec.rb +8 -0
  54. data/spec/mongoid/helpers/ransack_helper.rb +11 -0
  55. data/spec/mongoid/nodes/condition_spec.rb +34 -0
  56. data/spec/mongoid/nodes/grouping_spec.rb +13 -0
  57. data/spec/mongoid/predicate_spec.rb +155 -0
  58. data/spec/mongoid/search_spec.rb +446 -0
  59. data/spec/mongoid/support/mongoid.yml +6 -0
  60. data/spec/mongoid/support/schema.rb +128 -0
  61. data/spec/mongoid/translate_spec.rb +14 -0
  62. data/spec/mongoid_spec_helper.rb +59 -0
  63. data/spec/ransack/adapters/active_record/base_spec.rb +68 -35
  64. data/spec/ransack/dependencies_spec.rb +3 -1
  65. data/spec/ransack/helpers/form_builder_spec.rb +6 -6
  66. data/spec/ransack/helpers/form_helper_spec.rb +114 -47
  67. data/spec/ransack/nodes/condition_spec.rb +2 -2
  68. data/spec/ransack/search_spec.rb +2 -6
  69. data/spec/ransack/translate_spec.rb +1 -1
  70. data/spec/spec_helper.rb +2 -3
  71. data/spec/support/schema.rb +9 -0
  72. metadata +49 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c740816de011eb6b10728dc32b58e179304fad94
4
- data.tar.gz: 07fb384c320453fe1176fc9c51261721318fe708
3
+ metadata.gz: f794e84fb4595e61da2a692b091c475698170fda
4
+ data.tar.gz: 3c74ff882fc59a32b25c83155c0e7ab4922b013c
5
5
  SHA512:
6
- metadata.gz: 6647e2d472b4efd1e0051bd293698011c5a89ffdd096456c75da5b44f58b8ac825d3a5292d41a174e6b01e43bfd0bfc996685ee0fd30a13af91eaabb920162e3
7
- data.tar.gz: 09e01482d289cfca68527dfce6161a8cf028846da7d510d927b59e155792e1c82b2aa3fc02eec5a4667b47b0fa08a13eb0fb2d542f3e91b368917540d13ce7ed
6
+ metadata.gz: f70a119cfb73857c715feafa11ed85ad862f4439653e266586e2bcccf6523c5374229483f273e7aa5d2a8ecc8973a1b3cab221393d6cb5e240723db1d63b16ff
7
+ data.tar.gz: d16a78c96996d5b28ff151ea89a6eb1729743c185e6a88d002b25f03b8326e7fa395fe523a885a02298867e65c80d3a7ad190c3e16e14a89f70314b25db6d03d
@@ -1,32 +1,76 @@
1
+ services: mongodb
2
+
1
3
  language: ruby
2
4
 
3
5
  sudo: false
4
6
 
5
7
  rvm:
8
+ - 2.2
6
9
  - 2.1
7
10
  - 2.0
8
11
  - 1.9
9
12
 
10
13
  env:
11
- - RAILS=master DB=sqlite3
12
- - RAILS=master DB=mysql
13
- - RAILS=master DB=postgres
14
+ - RAILS=4-2-stable DB=mongodb
15
+ - RAILS=4-2-stable DB=sqlite3
16
+ - RAILS=4-2-stable DB=mysql
17
+ - RAILS=4-2-stable DB=postgres
18
+
19
+ - RAILS=4-1-stable DB=mongodb
14
20
  - RAILS=4-1-stable DB=sqlite3
15
21
  - RAILS=4-1-stable DB=mysql
16
22
  - RAILS=4-1-stable DB=postgres
23
+
17
24
  - RAILS=4-0-stable DB=sqlite3
18
25
  - RAILS=4-0-stable DB=mysql
19
26
  - RAILS=4-0-stable DB=postgres
27
+
20
28
  - RAILS=3-2-stable DB=sqlite
21
29
  - RAILS=3-2-stable DB=mysql
22
30
  - RAILS=3-2-stable DB=postgres
31
+
23
32
  - RAILS=3-1-stable DB=sqlite
24
33
  - RAILS=3-1-stable DB=mysql
25
34
  - RAILS=3-1-stable DB=postgres
35
+
26
36
  - RAILS=3-0-stable DB=sqlite
27
37
  - RAILS=3-0-stable DB=mysql
28
38
  - RAILS=3-0-stable DB=postgres
29
39
 
40
+ matrix:
41
+ include:
42
+ - rvm: 2.2
43
+ env: RAILS=master DB=sqlite3
44
+ - rvm: 2.2
45
+ env: RAILS=master DB=mysql
46
+ - rvm: 2.2
47
+ env: RAILS=master DB=postgres
48
+ exclude:
49
+ - rvm: 2.2
50
+ env: RAILS=3-0-stable DB=sqlite
51
+ - rvm: 2.2
52
+ env: RAILS=3-0-stable DB=mysql
53
+ - rvm: 2.2
54
+ env: RAILS=3-0-stable DB=postgres
55
+
56
+ allow_failures:
57
+ - env: RAILS=master DB=sqlite3
58
+ - env: RAILS=master DB=mysql
59
+ - env: RAILS=master DB=postgres
60
+
61
+ - rvm: 2.2
62
+ env: RAILS=3-2-stable DB=sqlite
63
+ - rvm: 2.2
64
+ env: RAILS=3-2-stable DB=mysql
65
+ - rvm: 2.2
66
+ env: RAILS=3-2-stable DB=postgres
67
+ - rvm: 2.2
68
+ env: RAILS=3-1-stable DB=sqlite
69
+ - rvm: 2.2
70
+ env: RAILS=3-1-stable DB=mysql
71
+ - rvm: 2.2
72
+ env: RAILS=3-1-stable DB=postgres
73
+
30
74
  before_script:
31
75
  - mysql -e 'create database ransack collate utf8_general_ci;'
32
76
  - mysql -e 'use ransack;show variables like "%character%";show variables like "%collation%";'
@@ -1,29 +1,116 @@
1
1
  # Change Log
2
- This change log was started in August 2014. All notable changes to this project
3
- henceforth should be documented here.
4
2
 
5
- ## Version 1.5.1 - 2014-10-30
3
+ ## Version 1.6.0 - 2015-01-12
6
4
  ### Added
7
5
 
8
- * Add base specs for search on fields with `_start` and `_end`.
6
+ * Add support for using Ransack with `Mongoid 4.0` without associations
7
+ ([PR #407](https://github.com/activerecord-hackery/ransack/pull/407)).
8
+
9
+ *Zhomart Mukhamejanov*
10
+
11
+ * Add support and tests for passing stringy booleans for ransackable scopes
12
+ ([PR #460](https://github.com/activerecord-hackery/ransack/pull/460)).
13
+
14
+ *Josh Kovach*
15
+
16
+ * Add an sort_link option to not display sort direction arrows
17
+ ([PR #473](https://github.com/activerecord-hackery/ransack/pull/473)).
18
+
19
+ *Fred Bergman*
20
+
21
+ * Numerous documentation improvements to the README, Contributing Guide and
22
+ wiki.
9
23
 
10
24
  *Jon Atack*
11
25
 
12
- * Add a failing spec for detecting attribute fields containing `_and_` that
13
- needs to be fixed. Method names containing `_and_` and `_or_` are still not
14
- parsed/detected correctly.
26
+ ### Fixed
27
+
28
+ * Fix passing arrays to ransackers with Rails 4.2 / Arel 6.0 (pull requests
29
+ [#486](https://github.com/activerecord-hackery/ransack/pull/486) and
30
+ [#488](https://github.com/activerecord-hackery/ransack/pull/488)).
31
+
32
+ *Idean Labib*
33
+
34
+ * Make `search_form_for`'s default `:as` option respect the custom search key
35
+ if it has been set
36
+ ([PR #470](https://github.com/activerecord-hackery/ransack/pull/470)).
37
+ Prior to this change, if you set a custom `search_key` option in the
38
+ Ransack initializer file, you'd have to also pass an `as: :whatever` option
39
+ to all of the search forms. Fixes
40
+ [#92](https://github.com/activerecord-hackery/ransack/issues/92).
41
+
42
+ *Robert Speicher*
43
+
44
+ * Fix sorting on polymorphic associations (missing downcase)
45
+ ([PR #467](https://github.com/activerecord-hackery/ransack/pull/467)).
46
+
47
+ *Eugen Neagoe*
48
+
49
+ * Fix Rails 5 / Arel 5 compatibility after the Arel and Active Record API
50
+ changed.
51
+
52
+ * Fix and add tests for sort_link `default_order` parsing if the option is set
53
+ as a string instead of symbol.
54
+
55
+ * Fix and add a test to handle `nil` in options passed to sort_link.
56
+
57
+ * Fix #search method name conflicts in the README.
15
58
 
16
59
  *Jon Atack*
17
60
 
61
+ ### Changed
62
+
63
+ * Refactor and DRY up FormHelper#SortLink. Encapsulate parsing into a
64
+ Plain Old Ruby Object with few public methods and small, private functional
65
+ methods. Limit mutations to explicit methods and mutate no ivars.
66
+
67
+ * Numerous speed improvements by using more specific Ruby methods like:
68
+ - `Hash#each_key` instead of `Hash#keys.each`
69
+ - `#none?` instead of `select#empty?`
70
+ - `#any?` instead of `#select` followed by `#any?`
71
+ - `#flat_map` instead of `#flatten` followed by `#map`
72
+ - `!include?` instead of `#none?`
73
+
74
+ * Replace `string#freeze` instances with top level constants to reduce string
75
+ allocations in Ruby < 2.1.
76
+
77
+ * Remove unneeded `Ransack::` namespacing on most of the constants.
78
+
79
+ * In enumerable methods, pass a symbol as an argument instead of a block.
80
+
81
+ * Update Travis-ci for Rails 5.0.0 and 4-2-stable.
82
+
83
+ * Update the Travis-ci tests and the Gemfile for Ruby 2.2.
84
+
85
+ * Replace `#search` with `#ransack` class methods in the README and wiki
86
+ code examples. Enabling the `#search` alias by default may possibly be
87
+ deprecated in the next major release (Ransack v.2.0.0) to address
88
+ [#369](https://github.com/activerecord-hackery/ransack/issues/369).
89
+
90
+ *Jon Atack*
91
+
92
+ ## Version 1.5.1 - 2014-10-30
18
93
  ### Fixed
19
94
 
20
- * Fix a regression caused by incorrect string constants in context.rb.
95
+ * Fix a regression caused by incorrect string constants in `context.rb`.
96
+
97
+ *Kazuhiro Nishiyama*
98
+
99
+ ### Added
100
+
101
+ * Add base specs for search on fields with `_start` and `_end`.
102
+
103
+ *Jon Atack*
21
104
 
22
- *Kazuhiro NISHIYAMA*
105
+ * Add a failing spec for detecting attribute fields containing `_and_` that
106
+ needs to be fixed. Attribute names containing `_and_` and `_or_` are still
107
+ not parsed/detected correctly.
108
+
109
+ *Jon Atack*
23
110
 
24
111
  ### Changed
25
112
 
26
- * Remove duplicate code in spec/support/schema.rb.
113
+ * Remove duplicate code in `spec/support/schema.rb`.
27
114
 
28
115
  *Jon Atack*
29
116
 
@@ -33,8 +120,8 @@ henceforth should be documented here.
33
120
 
34
121
  * Add support for multiple sort fields and default orders in Ransack
35
122
  `sort_link` helpers
36
- ([pull request](https://github.com/activerecord-hackery/ransack/pull/438)).
37
-
123
+ ([PR #438](https://github.com/activerecord-hackery/ransack/pull/438)).
124
+
38
125
  *Caleb Land*, *James u007*
39
126
 
40
127
  * Add tests for `lteq`, `lt`, `gteq` and `gt` predicates. They are also
@@ -44,15 +131,15 @@ henceforth should be documented here.
44
131
  *Jon Atack*
45
132
 
46
133
  * Add tests for unknown attribute names.
47
-
134
+
48
135
  *Joe Yates*
49
136
 
50
- * Add tests for attribute names containing '_or_' and '_and_'.
51
-
137
+ * Add tests for attribute names containing `_or_` and `_and_`.
138
+
52
139
  *Joe Yates*, *Jon Atack*
53
140
 
54
- * Add tests for attribute names ending with '_start' and '_end'.
55
-
141
+ * Add tests for attribute names ending with `_start` and `_end``.
142
+
56
143
  *Jon Atack*, *Timo Schilling*
57
144
 
58
145
  * Add tests for `start`, `not_start`, `end` and `not_end` predicates, with
@@ -164,9 +251,10 @@ henceforth should be documented here.
164
251
  * Rewrite much of the Ransack README documentation, including the
165
252
  Associations section code examples and the Authorizations section detailing
166
253
  how to whitelist attributes, associations, sorts and scopes.
167
-
254
+
168
255
  *Jon Atack*
169
256
 
257
+
170
258
  ## Version 1.3.0 - 2014-08-23
171
259
  ### Added
172
260
 
@@ -1,15 +1,31 @@
1
+ # Contributing to Ransack
2
+
3
+ Please take a moment to review this document in order to make the contribution
4
+ process easy and effective for everyone involved!
5
+
1
6
  Ransack is an open source project and we encourage contributions.
2
7
 
3
8
  ## Filing an issue
4
9
 
5
- When filing an issue on the Ransack project, please provide these details:
10
+ A bug is a _demonstrable problem_ that is caused by the code in the repository.
11
+ Good bug reports are extremely helpful! Please do not use the issue tracker for personal support requests.
6
12
 
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
- * Any relevant stack traces ("Full trace" preferred).
13
+ Guidelines for bug reports:
14
+
15
+ 1. **Use the GitHub issue search** &mdash; check if the issue has already been
16
+ reported.
17
+
18
+ 2. **Check if the issue has been fixed** &mdash; try to reproduce it using the
19
+ `master` branch in the repository.
20
+
21
+ 3. **Isolate and report the problem** &mdash; ideally create a reduced test
22
+ case.
23
+
24
+ When filing an issue, please provide these details:
10
25
 
11
- In 99% of cases, this information is enough to determine the cause and
12
- solution to the problem that is being described.
26
+ * A comprehensive list of steps to reproduce the issue, or - far better - **a failing spec**.
27
+ * The version (and branch) of Ransack *and* the versions of Rails, Ruby, and your operating system.
28
+ * Any relevant stack traces ("Full trace" preferred).
13
29
 
14
30
  Any issue that is open for 14 days without actionable information or activity
15
31
  will be marked as "stalled" and then closed. Stalled issues can be re-opened
@@ -20,40 +36,56 @@ if the information requested is provided.
20
36
  We gladly accept pull requests to fix bugs and, in some circumstances, add new
21
37
  features to Ransack.
22
38
 
39
+ If you're new to contributing to open source, welcome! It can seem scary, so
40
+ here is a [great blog post to help you get started]
41
+ (http://robots.thoughtbot.com/8-new-steps-for-fixing-other-peoples-code),
42
+ step by step.
43
+
23
44
  Before issuing a pull request, please make sure that all specs are passing,
24
45
  that any new features have test coverage, and that anything that breaks
25
46
  backward compatibility has a very good reason for doing so.
26
47
 
27
48
  Here's a quick guide:
28
49
 
29
- 1. Fork the repo.
50
+ 1. Fork the repo, clone it, create a thoughtfully-named branch for your changes,
51
+ and install the development dependencies by running `bundle install`.
30
52
 
31
- 2. Run the tests. We only take pull requests with passing tests, and it's great
32
- to know that you have a clean slate:
53
+ 2. Begin by running the tests. We only take pull requests with passing tests,
54
+ and it's great to know that you have a clean slate:
33
55
 
34
- $ bundle install
35
56
  $ bundle exec rake spec
36
57
 
37
- 3. Add a test for your change. Only refactoring and documentation changes
38
- require no new tests. If you are adding functionality or fixing a bug, we need
39
- a test!
58
+ 3. Hack away! Please use Ruby features that are compatible down to Ruby 1.9.
59
+ Since version 1.5, Ransack no longer maintains Ruby 1.8 compatibility.
60
+
61
+ 4. Add tests for your changes. Only refactoring and documentation changes
62
+ require no new tests. If you are adding functionality or fixing a bug, we
63
+ need a test!
64
+
65
+ 5. Make the tests pass.
66
+
67
+ 6. Update the Change Log. If you are adding new functionality, document it in
68
+ the README.
69
+
70
+ 7. Do not change the version number; we will do that on our end.
71
+
72
+ 8. If necessary, rebase your commits into logical chunks, without errors.
40
73
 
41
- 4. Make the test pass.
74
+ 9. Push the branch up to your fork on Github and submit a pull request. If the
75
+ changes will apply cleanly to the latest stable branches and master branch,
76
+ you will only need to submit one pull request.
42
77
 
43
- 5. Push to your fork and submit a pull request. If the changes will apply
44
- cleanly to the latest stable branches and master branch, you will only need
45
- to submit one pull request. If the pull request only contains documentation
46
- changes, please add `[skip ci]` to the commit message so that the Travis test
47
- suite does not needlessly run.
78
+ 10. If your pull request only contains documentation changes, please remember to
79
+ add `[skip ci]` to your commit message so the Travis test suite doesn't run
80
+ needlessly.
48
81
 
49
82
  At this point you're waiting on us. We like to at least comment on, if not
50
83
  accept, pull requests within three business days (and, typically, one business
51
84
  day). We may suggest some changes or improvements or alternatives.
52
85
 
53
- Some things that will increase the chance that your pull request is accepted,
54
- taken straight from the Ruby on Rails guide:
86
+ Some things that will increase the chance that your pull request is accepted:
55
87
 
56
- * Use Rails idioms and helpers.
88
+ * Use idiomatic Ruby and follow the syntax conventions below.
57
89
  * Include tests that fail without your code, and pass with it.
58
90
  * Update the README, the change log, the wiki documentation... anything that is
59
91
  affected by your contribution.
@@ -68,6 +100,7 @@ Syntax:
68
100
  * `a = b` and not `a=b`.
69
101
  * `a_method { |block| ... }` and not `a_method { | block | ... }` or
70
102
  `a_method{|block| ...}`.
71
- * Follow the conventions you see used in the source already.
103
+ * Prefer simplicity, readability, and maintainability over terseness.
104
+ * Follow the conventions you see used in the code already.
72
105
 
73
106
  And in case we didn't emphasize it enough: we love tests!
data/Gemfile CHANGED
@@ -5,35 +5,46 @@ 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'
8
+ if rails == 'master'
9
+ gem 'arel', github: 'rails/arel'
10
10
  end
11
11
 
12
12
  gem 'polyamorous', '~> 1.1'
13
13
 
14
+ gem 'pry'
15
+
14
16
  # Provide timezone information on Windows
15
17
  gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
16
18
 
17
19
  case rails
18
20
  when /\// # A path
19
21
  gem 'activesupport', path: "#{rails}/activesupport"
20
- gem 'activerecord', path: "#{rails}/activerecord"
22
+ gem 'activerecord', path: "#{rails}/activerecord", require: false
21
23
  gem 'actionpack', path: "#{rails}/actionpack"
22
24
  when /^v/ # A tagged version
23
25
  git 'git://github.com/rails/rails.git', :tag => rails do
24
26
  gem 'activesupport'
25
27
  gem 'activemodel'
26
- gem 'activerecord'
28
+ gem 'activerecord', require: false
27
29
  gem 'actionpack'
28
30
  end
29
31
  else
30
32
  git 'git://github.com/rails/rails.git', :branch => rails do
31
33
  gem 'activesupport'
32
34
  gem 'activemodel'
33
- gem 'activerecord'
35
+ gem 'activerecord', require: false
34
36
  gem 'actionpack'
35
37
  end
36
38
  if rails == '3-0-stable'
37
39
  gem 'mysql2', '< 0.3'
38
40
  end
39
41
  end
42
+
43
+ if ENV['DB'] =~ /mongodb/
44
+ gem 'mongoid', '~> 4.0.0', require: false
45
+ end
46
+
47
+ # Removed from Ruby 2.2 but needed for testing Rails 3.x.
48
+ group :test do
49
+ gem 'test-unit', '~> 3.0' if RUBY_VERSION >= '2.2'
50
+ end
data/README.md CHANGED
@@ -17,16 +17,26 @@ and backwards compatibility is not a design goal.
17
17
 
18
18
  Ransack enables the creation of both simple and
19
19
  [advanced](http://ransack-demo.herokuapp.com/users/advanced_search)
20
- search forms against your application's models (demo source code
20
+ search forms for your Ruby on Rails application (demo source code
21
21
  [here](https://github.com/activerecord-hackery/ransack_demo)).
22
22
  If you're looking for something that simplifies query generation at the model
23
23
  or controller layer, you're probably not looking for Ransack (or MetaSearch,
24
24
  for that matter). Try [Squeel](https://github.com/activerecord-hackery/squeel)
25
25
  instead.
26
26
 
27
+ If you're viewing this at
28
+ [github.com/activerecord-hackery/ransack](https://github.com/activerecord-hackery/ransack),
29
+ you're reading the documentation for the master branch with the latest features.
30
+ [View documentation for the last release (1.6.0).](https://github.com/activerecord-hackery/ransack/tree/v.1.6.0)
31
+
27
32
  ## Getting started
28
33
 
29
- Ransack is currently compatible with Rails 3.x, 4.0, 4.1 and 4.2.
34
+ Ransack is compatible with Rails 3 and 4 (including 4.2) on Ruby 1.9 and later.
35
+ We try to keep it functioning with Rails master too, although frequent changes
36
+ in Arel and Active Record make that a moving target. Ransack works
37
+ out-of-the-box with Active Record and features new support for Mongoid 4.0
38
+ (without associations, further details below). If you are on Ruby 1.8, you may
39
+ need to use an earlier version of Ransack like 1.3.0.
30
40
 
31
41
  In your Gemfile, for the last officially released Ransack gem:
32
42
 
@@ -34,7 +44,7 @@ In your Gemfile, for the last officially released Ransack gem:
34
44
  gem 'ransack'
35
45
  ```
36
46
 
37
- Or, if you would like to use the latest updates:
47
+ Or, if you would like to use the latest updates, use the `master` branch:
38
48
 
39
49
  ```ruby
40
50
  gem 'ransack', github: 'activerecord-hackery/ransack'
@@ -54,6 +64,15 @@ To use one of the branches, for example the `rails-4.1` branch:
54
64
  gem 'ransack', github: 'activerecord-hackery/ransack', branch: 'rails-4.1'
55
65
  ```
56
66
 
67
+ If you are using Rails master, be advised that Ransack master does not yet work
68
+ with the breaking changes in Rails master and Arel master added since December
69
+ 2014. The most recent working commits are:
70
+
71
+ ```ruby
72
+ gem 'rails', github: 'rails/rails', ref: '266ff70'
73
+ gem 'arel', github: 'rails/arel', ref: '008445d'
74
+ ```
75
+
57
76
  ## Usage
58
77
 
59
78
  Ransack can be used in one of two modes, simple or advanced.
@@ -77,24 +96,29 @@ If you're coming from MetaSearch, things to note:
77
96
  3. Common ActiveRecord::Relation methods are no longer delegated by the
78
97
  search object. Instead, you will get your search results (an
79
98
  ActiveRecord::Relation in the case of the ActiveRecord adapter) via a call to
80
- `Search#result`.
81
-
99
+ `Ransack#result`.
100
+
82
101
  4. If passed `distinct: true`, `result` will generate a `SELECT DISTINCT` to
83
102
  avoid returning duplicate rows, even if conditions on a join would otherwise
84
- result in some.
103
+ result in some. It generates the same SQL as calling `uniq` on the relation.
85
104
 
86
105
  Please note that for many databases, a sort on an associated table's columns
87
106
  may result in invalid SQL with `distinct: true` -- in those cases, you're on
88
107
  your own, and will need to modify the result as needed to allow these queries
89
- to work. If `distinct: true` is causing you problems, another way to remove
90
- duplicates is to call `#to_a.uniq` on your collection instead (see the next
91
- section below).
108
+ to work.
109
+
110
+ If `distinct: true` or `uniq` is causing invalid SQL, another way to remove
111
+ duplicates is to call `to_a.uniq` on the collection at the end (see the next
112
+ section below) -- with the caveat that the de-duping is taking place in Ruby
113
+ instead of in SQL, which is potentially slower and uses more memory, and that
114
+ it may display awkwardly with pagination if the number of results is greater
115
+ than the page size.
92
116
 
93
117
  ####In your controller
94
118
 
95
119
  ```ruby
96
120
  def index
97
- @q = Person.search(params[:q])
121
+ @q = Person.ransack(params[:q])
98
122
  @people = @q.result(distinct: true)
99
123
  end
100
124
  ```
@@ -103,8 +127,9 @@ this example, with preloading each Person's Articles and pagination):
103
127
 
104
128
  ```ruby
105
129
  def index
106
- @q = Person.search(params[:q])
130
+ @q = Person.ransack(params[:q])
107
131
  @people = @q.result.includes(:articles).page(params[:page])
132
+
108
133
  # or use `to_a.uniq` to remove duplicates (can also be done in the view):
109
134
  @people = @q.result.includes(:articles).page(params[:page]).to_a.uniq
110
135
  end
@@ -163,6 +188,14 @@ column title or a default sort order:
163
188
  <%= sort_link(@q, :name, 'Last Name', default_order: :desc) %>
164
189
  ```
165
190
 
191
+ With a polymorphic association, you may need to specify the name of the link
192
+ explicitly to avoid an `uninitialized constant Model::Xxxable` error (see issue
193
+ [#421](https://github.com/activerecord-hackery/ransack/issues/421)):
194
+
195
+ ```erb
196
+ <%= sort_link(@q, :xxxable_of_Ymodel_type_some_attribute, 'Attribute Name') %>
197
+ ```
198
+
166
199
  You can also sort on multiple fields by specifying an ordered array:
167
200
 
168
201
  ```erb
@@ -184,6 +217,13 @@ This example toggles the sort directions of both fields, by default
184
217
  initially sorting the `last_name` field by ascending order, and the
185
218
  `first_name` field by descending order.
186
219
 
220
+ The sort link may be displayed without the order indicator arrow by passing
221
+ `hide_indicator: true`:
222
+
223
+ ```erb
224
+ <%= sort_link(@q, :name, hide_indicator: true) %>
225
+ ```
226
+
187
227
  ### Advanced Mode
188
228
 
189
229
  "Advanced" searches (ab)use Rails' nested attributes functionality in order to
@@ -226,12 +266,26 @@ construct much more complex search forms, such as the one on the
226
266
  ### Ransack #search method
227
267
 
228
268
  Ransack will try to to make `#search` available in your models, but in the case
229
- that `#search` has already been defined, you can use `#ransack` instead. For
230
- example the following would be equivalent:
269
+ that `#search` has already been defined, you can always use the default
270
+ `#ransack` method. For example, the following would be equivalent:
231
271
 
232
272
  ```ruby
233
- Article.search(params[:q])
234
273
  Article.ransack(params[:q])
274
+ Article.search(params[:q])
275
+ ```
276
+
277
+ Users have reported issues of name conflicts with other gems, so `#search` may
278
+ possibly be deprecated in the next major version of Ransack (2.0).
279
+
280
+ For now, if Ransack's `#search` method conflicts with the name of another
281
+ method named `search` in your code or another gem, you may resolve it either by
282
+ patching the `extended` class_method in `Ransack::Adapters::ActiveRecord::Base`
283
+ to remove the line `alias :search :ransack unless base.respond_to? :search`, or
284
+ by placing the following line in your Ransack initializer file at
285
+ `config/initializers/ransack.rb`:
286
+
287
+ ```ruby
288
+ Ransack::Adapters::ActiveRecord::Base.class_eval('remove_method :search')
235
289
  ```
236
290
 
237
291
  ### Associations
@@ -267,7 +321,7 @@ end
267
321
  ```ruby
268
322
  class SupervisorsController < ApplicationController
269
323
  def index
270
- @q = Supervisor.search(params[:q])
324
+ @q = Supervisor.ransack(params[:q])
271
325
  @supervisors = @q.result.includes(:department, :employees)
272
326
  end
273
327
  end
@@ -289,7 +343,7 @@ end
289
343
  <%= f.submit "search" %>
290
344
  <% end %>
291
345
  ...
292
- <%= content_tag :table %>
346
+ <%= content_tag :table do %>
293
347
  <%= content_tag :th, sort_link(@q, :last_name) %>
294
348
  <%= content_tag :th, sort_link(@q, 'departments.title') %>
295
349
  <%= content_tag :th, sort_link(@q, 'employees.last_name') %>
@@ -318,7 +372,7 @@ class methods in your models to apply selective authorization:
318
372
  Here is how these four methods are implemented in Ransack:
319
373
 
320
374
  ```ruby
321
- # Ransackable_attributes, by default, returns all column names
375
+ # `ransackable_attributes` by default returns all column names
322
376
  # and any defined ransackers as an array of strings.
323
377
  # For overriding with a whitelist array of strings.
324
378
  #
@@ -326,7 +380,7 @@ Here is how these four methods are implemented in Ransack:
326
380
  column_names + _ransackers.keys
327
381
  end
328
382
 
329
- # Ransackable_associations, by default, returns the names
383
+ # `ransackable_associations` by default returns the names
330
384
  # of all associations as an array of strings.
331
385
  # For overriding with a whitelist array of strings.
332
386
  #
@@ -334,7 +388,7 @@ Here is how these four methods are implemented in Ransack:
334
388
  reflect_on_all_associations.map { |a| a.name.to_s }
335
389
  end
336
390
 
337
- # Ransortable_attributes, by default, returns the names
391
+ # `ransortable_attributes` by default returns the names
338
392
  # of all attributes available for sorting as an array of strings.
339
393
  # For overriding with a whitelist array of strings.
340
394
  #
@@ -342,7 +396,7 @@ Here is how these four methods are implemented in Ransack:
342
396
  ransackable_attributes(auth_object)
343
397
  end
344
398
 
345
- # Ransackable_scopes, by default, returns an empty array
399
+ # `ransackable_scopes` by default returns an empty array
346
400
  # i.e. no class methods/scopes are authorized.
347
401
  # For overriding with a whitelist array of *symbols*.
348
402
  #
@@ -376,7 +430,7 @@ class Article < ActiveRecord::Base
376
430
  super
377
431
  else
378
432
  # whitelist only the title and body attributes for other users
379
- super & %w(title body)
433
+ super & %w(title body)
380
434
  end
381
435
  end
382
436
  end
@@ -388,10 +442,10 @@ Here is example code for the `articles_controller`:
388
442
  class ArticlesController < ApplicationController
389
443
 
390
444
  def index
391
- @q = Article.search(params[:q], auth_object: set_ransack_auth_object)
445
+ @q = Article.ransack(params[:q], auth_object: set_ransack_auth_object)
392
446
  @articles = @q.result
393
447
  end
394
-
448
+
395
449
  private
396
450
 
397
451
  def set_ransack_auth_object
@@ -404,21 +458,21 @@ Trying it out in `rails console`:
404
458
 
405
459
  ```ruby
406
460
  > Article
407
- => Article(id: integer, person_id: integer, title: string, body: text)
461
+ => Article(id: integer, person_id: integer, title: string, body: text)
408
462
 
409
463
  > Article.ransackable_attributes
410
- => ["title", "body"]
464
+ => ["title", "body"]
411
465
 
412
466
  > Article.ransackable_attributes(:admin)
413
- => ["id", "person_id", "title", "body"]
467
+ => ["id", "person_id", "title", "body"]
414
468
 
415
- > Article.search(id_eq: 1).result.to_sql
469
+ > Article.ransack(id_eq: 1).result.to_sql
416
470
  => SELECT "articles".* FROM "articles" # Note that search param was ignored!
417
471
 
418
- > Article.search({ id_eq: 1 }, { auth_object: nil }).result.to_sql
472
+ > Article.ransack({ id_eq: 1 }, { auth_object: nil }).result.to_sql
419
473
  => SELECT "articles".* FROM "articles" # Search param still ignored!
420
474
 
421
- > Article.search({ id_eq: 1 }, { auth_object: :admin }).result.to_sql
475
+ > Article.ransack({ id_eq: 1 }, { auth_object: :admin }).result.to_sql
422
476
  => SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1
423
477
  ```
424
478
 
@@ -456,11 +510,17 @@ class Employee < ActiveRecord::Base
456
510
  end
457
511
  end
458
512
 
459
- Employee.search({ active: true, hired_since: '2013-01-01' })
513
+ Employee.ransack({ active: true, hired_since: '2013-01-01' })
460
514
 
461
- Employee.search({ salary_gt: 100_000 }, { auth_object: current_user })
515
+ Employee.ransack({ salary_gt: 100_000 }, { auth_object: current_user })
462
516
  ```
463
517
 
518
+ If the `true` value is being passed via url params or by some other mechanism
519
+ that will convert it to a string (i.e. `active: 'true'` instead of
520
+ `active: true`), the true value will *not* be passed to the scope. If you want
521
+ to pass a `'true'` string to the scope, you should wrap it in an array (i.e.
522
+ `active: ['true']`).
523
+
464
524
  Scopes are a recent addition to Ransack and currently have a few caveats:
465
525
  First, a scope involving child associations needs to be defined in the parent
466
526
  table model, not in the child model. Second, scopes with an array as an
@@ -469,10 +529,8 @@ wrapped in an array to function (see
469
529
  [this issue](https://github.com/activerecord-hackery/ransack/issues/404)),
470
530
  which is not compatible with Ransack form helpers. For this use case, it may be
471
531
  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!
532
+ (https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers) instead,
533
+ where feasible. Pull requests with solutions and tests are welcome!
476
534
 
477
535
  ### Grouping queries by OR instead of AND
478
536
 
@@ -484,7 +542,7 @@ You can easily try it in your controller code by changing `params[:q]` in the
484
542
 
485
543
  ```ruby
486
544
  def index
487
- @q = Artist.search(params[:q].try(:merge, m: 'or'))
545
+ @q = Artist.ransack(params[:q].try(:merge, m: 'or'))
488
546
  @artists = @q.result
489
547
  end
490
548
  ```
@@ -496,7 +554,7 @@ quickly.
496
554
  Alternatively, trying it in the Rails console:
497
555
 
498
556
  ```ruby
499
- artists = Artist.search(name_cont: 'foo', style_cont: 'bar', m: 'or')
557
+ artists = Artist.ransack(name_cont: 'foo', style_cont: 'bar', m: 'or')
500
558
  => Ransack::Search<class: Artist, base: Grouping <conditions: [
501
559
  Condition <attributes: ["name"], predicate: cont, values: ["foo"]>,
502
560
  Condition <attributes: ["style"], predicate: cont, values: ["bar"]>
@@ -515,7 +573,7 @@ This works with associations as well. Imagine an Artist model that has many
515
573
  Memberships, and many Musicians through Memberships:
516
574
 
517
575
  ```ruby
518
- artists = Artist.search(name_cont: 'foo', musicians_email_cont: 'bar', m: 'or')
576
+ artists = Artist.ransack(name_cont: 'foo', musicians_email_cont: 'bar', m: 'or')
519
577
  => Ransack::Search<class: Artist, base: Grouping <conditions: [
520
578
  Condition <attributes: ["name"], predicate: cont, values: ["foo"]>,
521
579
  Condition <attributes: ["musicians_email"], predicate: cont, values: ["bar"]>
@@ -591,12 +649,30 @@ en:
591
649
  title: Old Ransack Namespaced Title
592
650
  ```
593
651
 
652
+ ## Mongoid
653
+
654
+ Ransack now works with Mongoid in the same way as Active Record, except that
655
+ with Mongoid, associations are not currently supported. A demo app may be found
656
+ [here](http://ransack-mongodb-demo.herokuapp.com/) and the demo source code is
657
+ [here](https://github.com/Zhomart/ransack-mongodb-demo). A `result` method
658
+ called on a `ransack` search returns a `Mongoid::Criteria` object:
659
+
660
+ ```ruby
661
+ @q = Person.ransack(params[:q])
662
+ @people = @q.result # => Mongoid::Criteria
663
+
664
+ # or you can add more Mongoid queries
665
+ @people = @q.result.active.order_by(updated_at: -1).limit(10)
666
+ ```
667
+
594
668
  ## Semantic Versioning
595
669
 
596
670
  Ransack attempts to follow semantic versioning in the format of `x.y.z`, where:
597
671
 
598
672
  `x` stands for a major version (new features that are not backward-compatible).
673
+
599
674
  `y` stands for a minor version (new features that are backward-compatible).
675
+
600
676
  `z` stands for a patch (bug fixes).
601
677
 
602
678
  In other words: `Major.Minor.Patch`.