ransack 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40b269c3c65d60bdd34562075a2a3aaa1e2c500f
4
- data.tar.gz: d2520b91acbc39e7dcbe534d32294e7e0b01f512
3
+ metadata.gz: d33a76673ff5b03a95d1b2ea72c5fcc552fc24a3
4
+ data.tar.gz: 061c963998e43b654a28e0b3e7e9501feee14192
5
5
  SHA512:
6
- metadata.gz: c1152e4bde37b2f1b6dc78f888d51e2438c678ca366f54e54bf6baf9aecf7167e23e0119e24730dd94599c0888d68a2acba2a094093679f68e9c405866d774df
7
- data.tar.gz: b7be091d8256745c1feddc3e614432227714ee17b57f40ea9517309837384c486d9619971174966df7f8eafc71521ef7c09c149df639ead8bce4e98c9eab4a6b
6
+ metadata.gz: aa17a37043b1924961e17631865374576b78584068785c91331c06567b285ce10764b837c78f54f740570696e2ffd620e6681a391600074f2cc33d5d73956a1c
7
+ data.tar.gz: 7f3253f6d31f941546e0244389dcff4be6ec55e90511954c0eb0151447a27051b2c98a2d1b8e57ed89c279e98c1c608c5ee24a56115f8095aeed2038130ff7cb
@@ -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
 
@@ -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 version of Rails and Ruby.
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 documentation, the surrounding one, examples elsewhere, guides,
59
- whatever is affected by your contribution
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 &&/|| over and/or.
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 lighter and somewhat faster-running because they do not have to
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
- #####1. Ransack's `search_form_for` helper replaces `form_for` for creating the view search form:
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
- #####2. 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:
149
155
 
150
156
  ```erb
151
- <%= content_tag :th, sort_link(@q, :name) %>
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
- <%= content_tag :th, sort_link(@q, :name, 'Last Name', default_order: :desc) %>
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
- def ransackable_attributes(auth_object = nil)
295
- # By default returns all column names and any defined ransackers as an array
296
- # of strings. For overriding with a whitelist array of strings.
297
- column_names + _ransackers.keys
298
- end
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
- def ransackable_associations(auth_object = nil)
301
- # By default returns the names of all associations as an array of strings.
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
- reflect_on_all_associations.map { |a| a.name.to_s }
304
- end
332
+ #
333
+ def ransackable_associations(auth_object = nil)
334
+ reflect_on_all_associations.map { |a| a.name.to_s }
335
+ end
305
336
 
306
- def ransortable_attributes(auth_object = nil)
307
- # By default returns the names of all attributes for sorting as an array of
308
- # strings. For overriding with a whitelist array of strings.
309
- ransackable_attributes(auth_object)
310
- end
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
- def ransackable_scopes(auth_object = nil)
313
- # By default returns an empty array, i.e. no class methods/scopes
314
- # are authorized. For overriding with a whitelist array of *symbols*.
315
- []
316
- end
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) { (where active: boolean) }
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 want to combine form builders of ransack and SimpleForm, just set the
483
- RANSACK_FORM_BUILDER environment variable before Rails started, e.g. in
484
- ``config/application.rb`` before ``require 'rails/all'`` and of course use
485
- ``gem 'simple_form'`` in your ``Gemfile``:
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 request with tests that
508
- pass is even better! Before filing an issue or pull request, be sure to read
509
- the [Contributing Guide](CONTRIBUTING.md).
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 ? '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 ' AND '
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