ransack 1.8.3 → 1.8.4

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: d068e0ef0efe6ce1a4afdb11cc36361f94bbcf68
4
- data.tar.gz: 2ab905dd3037f405cfc262e2440cbfa557c5a799
3
+ metadata.gz: c8e6d1b7f6033421d1b31eff646ed9a001e372a3
4
+ data.tar.gz: 9a2736272f385849dc81f3a5f915c40ccde4d74e
5
5
  SHA512:
6
- metadata.gz: 354a8a5fc605f5efb7da6d1b78544f93780293418ac9a4578ae395fb608dbd69d301d5a129fbc6cf20c46427427fbeba04b0f7ea040b54771aaecbd31cf174ac
7
- data.tar.gz: 388a7b733a5460acd980703c6d918077fc27e4777f8acf0b2f3c72b696664c1ef9997c477de74a772ea776eb56521d65cda03bb7f190441575801a4d65b479d6
6
+ metadata.gz: 701f44cf5ed1ffa5c4c28ddf7267270161affdc70e6c5feffa1cd73e6fca16ab1438b836476337b41e25f67cfa71c5c4a51943f7848ea65150aeda5dd9ad2b8b
7
+ data.tar.gz: 221fc344c558b0c152363ecee786b9be06bb2d45460af5c0942485f56d36856d465c4ca039e248c9d879b8d6d44ebbff8b22e43d0e6ab66fef94293cfe1c6561
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- ## Unreleased
3
+ ## Version 1.8.3 - 2017-06-15
4
4
 
5
5
  ### Added
6
6
 
@@ -141,30 +141,17 @@
141
141
 
142
142
  *Marcel Eeken*
143
143
 
144
- * Add Taiwanese Hokkien/Mandarin i18n locale file (`zh-TW.yml`). PR
145
- [#674](https://github.com/activerecord-hackery/ransack/pull/674).
146
-
147
- *Sibevin Wang*
148
-
149
- * Add Danish i18n locale file (`da.yml`). PR
150
- [#663](https://github.com/activerecord-hackery/ransack/pull/663).
151
-
152
- *Kasper Johansen*
153
-
154
- * Add Brazilian Portuguese i18n locale file (`pt-BR.yml`). PR
155
- [#581](https://github.com/activerecord-hackery/ransack/pull/581).
156
-
157
- *Diego Henrique Domingues*
158
-
159
- * Add Indonesian (Bahasa) i18n locale file (`id.yml`). PR
160
- [#612](https://github.com/activerecord-hackery/ransack/pull/612).
161
-
162
- *Adam Pahlevi Baihaqi*
163
-
164
- * Add Japanese i18n locale file (`ja.yml`). PR
165
- [#622](https://github.com/activerecord-hackery/ransack/pull/622).
166
-
167
- *Masanobu Mizutani*
144
+ * Add i18n locale files:
145
+ * Taiwanese Hokkien/Mandarin (`zh-TW.yml`). PR
146
+ [#674](https://github.com/activerecord-hackery/ransack/pull/674). *Sibevin Wang*
147
+ * Danish (`da.yml`). PR
148
+ [#663](https://github.com/activerecord-hackery/ransack/pull/663). *Kasper Johansen*
149
+ * Brazilian Portuguese (`pt-BR.yml`). PR
150
+ [#581](https://github.com/activerecord-hackery/ransack/pull/581). *Diego Henrique Domingues*
151
+ * Indonesian (Bahasa) (`id.yml`). PR
152
+ [#612](https://github.com/activerecord-hackery/ransack/pull/612). *Adam Pahlevi Baihaqi*
153
+ * Japanese (`ja.yml`). PR
154
+ [#622](https://github.com/activerecord-hackery/ransack/pull/622). *Masanobu Mizutani*
168
155
 
169
156
  ### Fixed
170
157
 
data/README.md CHANGED
@@ -1,11 +1,8 @@
1
1
  # Ransack
2
2
 
3
- [![Build Status](https://travis-ci.org/activerecord-hackery/ransack.svg)]
4
- (https://travis-ci.org/activerecord-hackery/ransack)
5
- [![Gem Version](https://badge.fury.io/rb/ransack.svg)]
6
- (http://badge.fury.io/rb/ransack)
7
- [![Code Climate](https://codeclimate.com/github/activerecord-hackery/ransack/badges/gpa.svg)]
8
- (https://codeclimate.com/github/activerecord-hackery/ransack)
3
+ [![Build Status](https://travis-ci.org/activerecord-hackery/ransack.svg)](https://travis-ci.org/activerecord-hackery/ransack)
4
+ [![Gem Version](https://badge.fury.io/rb/ransack.svg)](http://badge.fury.io/rb/ransack)
5
+ [![Code Climate](https://codeclimate.com/github/activerecord-hackery/ransack/badges/gpa.svg)](https://codeclimate.com/github/activerecord-hackery/ransack)
9
6
 
10
7
  Ransack is a rewrite of [MetaSearch](https://github.com/activerecord-hackery/meta_search)
11
8
  created by [Ernie Miller](http://twitter.com/erniemiller)
@@ -203,13 +200,18 @@ initially sorting the `last_name` field by ascending order, and the
203
200
 
204
201
  The sort link order indicator arrows may be globally customized by setting a
205
202
  `custom_arrows` option in an initializer file like
206
- `config/initializers/ransack.rb`:
203
+ `config/initializers/ransack.rb`.
204
+
205
+ You can also enable a `default_arrow` which is displayed on all sortable fields
206
+ which are not currently used in the sorting. This is disabled by default so
207
+ nothing will be displayed:
207
208
 
208
209
  ```ruby
209
210
  Ransack.configure do |c|
210
211
  c.custom_arrows = {
211
212
  up_arrow: '<i class="custom-up-arrow-icon"></i>',
212
- down_arrow: 'U+02193'
213
+ down_arrow: 'U+02193',
214
+ default_arrow: '<i class="default-arrow-icon"></i>'
213
215
  }
214
216
  end
215
217
  ```
@@ -495,6 +497,14 @@ def index
495
497
  end
496
498
  ```
497
499
 
500
+ #### `PG::UndefinedFunction: ERROR: could not identify an equality operator for type json`
501
+
502
+ If you get the above error while using `distinct: true` that means that
503
+ one of the columns that Ransack is selecting is a `json` column.
504
+ PostgreSQL does not provide comparison operators for the `json` type. While
505
+ it is possible to work around this, in practice it's much better to convert those
506
+ to `jsonb`, as [recommended by the PostgreSQL documentation](https://www.postgresql.org/docs/9.6/static/datatype-json.html).
507
+
498
508
  ### Authorization (whitelisting/blacklisting)
499
509
 
500
510
  By default, searching and sorting are authorized on any column of your model
@@ -342,15 +342,25 @@ module Ransack
342
342
  def extract_joins(association)
343
343
  parent = @join_dependency.join_root
344
344
  reflection = association.reflection
345
- join_constraints = association.join_constraints(
346
- parent.table,
347
- parent.base_klass,
348
- association,
349
- Arel::Nodes::OuterJoin,
350
- association.tables,
351
- reflection.scope_chain,
352
- reflection.chain
353
- )
345
+ join_constraints = if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_1
346
+ association.join_constraints(
347
+ parent.table,
348
+ parent.base_klass,
349
+ association,
350
+ Arel::Nodes::OuterJoin,
351
+ association.tables,
352
+ reflection.scope_chain,
353
+ reflection.chain
354
+ )
355
+ else
356
+ association.join_constraints(
357
+ parent.table,
358
+ parent.base_klass,
359
+ Arel::Nodes::OuterJoin,
360
+ association.tables,
361
+ reflection.chain
362
+ )
363
+ end
354
364
  join_constraints.to_a.flatten
355
365
  end
356
366
 
@@ -12,6 +12,7 @@ module Ransack
12
12
  :hide_sort_order_indicators => false,
13
13
  :up_arrow => '&#9660;'.freeze,
14
14
  :down_arrow => '&#9650;'.freeze,
15
+ :default_arrow => nil,
15
16
  :sanitize_scope_args => true
16
17
  }
17
18
 
@@ -83,20 +84,25 @@ module Ransack
83
84
  # up_arrow: '&#9660;'
84
85
  # down_arrow: '&#9650;'
85
86
  #
86
- # One or both defaults may be globally overridden in an initializer file
87
+ # There is also a default arrow which is displayed if a column is not sorted.
88
+ # By default this is nil so nothing will be displayed.
89
+ #
90
+ # Any of the defaults may be globally overridden in an initializer file
87
91
  # like `config/initializers/ransack.rb` as follows:
88
92
  #
89
93
  # Ransack.configure do |config|
90
- # # Globally set the up arrow to an icon and the down arrow to unicode.
94
+ # # Globally set the up arrow to an icon, and the down and default arrows to unicode.
91
95
  # config.custom_arrows = {
92
96
  # up_arrow: '<i class="fa fa-long-arrow-up"></i>',
93
- # down_arrow: 'U+02193'
97
+ # down_arrow: 'U+02193',
98
+ # default_arrow: 'U+11047'
94
99
  # }
95
100
  # end
96
101
  #
97
102
  def custom_arrows=(opts = {})
98
103
  self.options[:up_arrow] = opts[:up_arrow].freeze if opts[:up_arrow]
99
104
  self.options[:down_arrow] = opts[:down_arrow].freeze if opts[:down_arrow]
105
+ self.options[:default_arrow] = opts[:default_arrow].freeze if opts[:default_arrow]
100
106
  end
101
107
 
102
108
  # Ransack sanitizes many values in your custom scopes into booleans.
@@ -46,6 +46,7 @@ module Ransack
46
46
  CONT = 'cont'.freeze
47
47
 
48
48
  RAILS_4_1 = '4.1'.freeze
49
+ RAILS_5_1 = '5.1'.freeze
49
50
 
50
51
  RANSACK_SLASH_SEARCHES = 'ransack/searches'.freeze
51
52
  RANSACK_SLASH_SEARCHES_SLASH_SEARCH = 'ransack/searches/search'.freeze
@@ -49,7 +49,7 @@ module Ransack
49
49
  unless Search === search
50
50
  raise TypeError, 'First argument must be a Ransack::Search!'
51
51
  end
52
- args.unshift(capture(&block)) if block_given?
52
+ args[args.first.is_a?(Array) ? 1 : 0, 0] = capture(&block) if block_given?
53
53
  s = SortLink.new(search, attribute, args, params, &block)
54
54
  link_to(s.name, url(routing_proxy, s.url_options), s.html_options(args))
55
55
  end
@@ -117,6 +117,10 @@ module Ransack
117
117
  Ransack.options[:down_arrow]
118
118
  end
119
119
 
120
+ def default_arrow
121
+ Ransack.options[:default_arrow]
122
+ end
123
+
120
124
  def name
121
125
  [ERB::Util.h(@label_text), order_indicator]
122
126
  .compact
@@ -209,7 +213,8 @@ module Ransack
209
213
  end
210
214
 
211
215
  def order_indicator
212
- return if @hide_indicator || no_sort_direction_specified?
216
+ return if @hide_indicator
217
+ return default_arrow if no_sort_direction_specified?
213
218
  if @current_dir == 'desc'.freeze
214
219
  up_arrow
215
220
  else
@@ -0,0 +1,70 @@
1
+ it:
2
+ ransack:
3
+ search: "cerca"
4
+ predicate: "predicato"
5
+ and: "e"
6
+ or: "o"
7
+ any: "qualsiasi"
8
+ all: "tutti"
9
+ combinator: "combinatore"
10
+ attribute: "attributo"
11
+ value: "valore"
12
+ condition: "condizione"
13
+ sort: "ordinamento"
14
+ asc: "crescente"
15
+ desc: "decrescente"
16
+ predicates:
17
+ eq: "uguale a"
18
+ eq_any: "uguale ad almeno un"
19
+ eq_all: "uguale ad ognuno"
20
+ not_eq: "diverso da"
21
+ not_eq_any: "diverso da uno qualsiasi"
22
+ not_eq_all: "diverso da tutti"
23
+ matches: "combacia con"
24
+ matches_any: "combacia con almeno un"
25
+ matches_all: "combacia con tutti"
26
+ does_not_match: "non corrisponde"
27
+ does_not_match_any: "non corrisponde ad uno qualsiasi"
28
+ does_not_match_all: "non corrisponde con nessuno"
29
+ lt: "minore di"
30
+ lt_any: "minore di almeno un"
31
+ lt_all: "minore di tutti"
32
+ lteq: "minore o uguale a"
33
+ lteq_any: "minore o uguale ad almeno un"
34
+ lteq_all: "minore o uguale a tutti"
35
+ gt: "maggiore di"
36
+ gt_any: "maggiore di almeno un"
37
+ gt_all: "maggiore di tutti"
38
+ gteq: "maggiore o uguale a"
39
+ gteq_any: "maggiore o uguale ad almeno un"
40
+ gteq_all: "maggiore o uguale a tutti"
41
+ in: "in"
42
+ in_any: "in almeno un"
43
+ in_all: "in tutti"
44
+ not_in: "non in"
45
+ not_in_any: "non in almeno un"
46
+ not_in_all: "non in tutti"
47
+ cont: "contiene"
48
+ cont_any: "contiene almeno un"
49
+ cont_all: "contiene tutti"
50
+ not_cont: "non contiene"
51
+ not_cont_any: "non contiene un qualsiasi"
52
+ not_cont_all: "non contiene nessuno"
53
+ start: "inizia con"
54
+ start_any: "inizia con almeno un"
55
+ start_all: "inizia con tutti"
56
+ not_start: "non inizia con"
57
+ not_start_any: "non inizia con uno qualsiasi"
58
+ not_start_all: "non inizia con nessuno"
59
+ end: "finisce con"
60
+ end_any: "finisce con almeno un"
61
+ end_all: "finisce con tutti"
62
+ not_end: "non finisce con"
63
+ not_end_any: "non finisce con uno qualsiasi"
64
+ not_end_all: "non finisce con nessuno"
65
+ 'true': "è vero"
66
+ 'false': "è falso"
67
+ present: "è presente"
68
+ blank: "è vuoto"
69
+ 'null': "è nullo"
70
+ not_null: "non è nullo"
@@ -23,87 +23,93 @@ module Ransack
23
23
  end
24
24
 
25
25
  def cast(type)
26
- case type
27
- when :date
28
- cast_to_date(value)
29
- when :datetime, :timestamp, :time
30
- cast_to_time(value)
31
- when :boolean
32
- cast_to_boolean(value)
33
- when :integer
34
- cast_to_integer(value)
35
- when :float
36
- cast_to_float(value)
37
- when :decimal
38
- cast_to_decimal(value)
39
- else
40
- cast_to_string(value)
41
- end
42
- end
26
+ case type
27
+ when :date
28
+ cast_to_date(value)
29
+ when :datetime, :timestamp, :time
30
+ cast_to_time(value)
31
+ when :boolean
32
+ cast_to_boolean(value)
33
+ when :integer
34
+ cast_to_integer(value)
35
+ when :float
36
+ cast_to_float(value)
37
+ when :decimal
38
+ cast_to_decimal(value)
39
+ when :money
40
+ cast_to_money(value)
41
+ else
42
+ cast_to_string(value)
43
+ end
44
+ end
43
45
 
44
- def cast_to_date(val)
45
- if val.respond_to?(:to_date)
46
- val.to_date rescue nil
47
- else
48
- y, m, d = *[val].flatten
49
- m ||= 1
50
- d ||= 1
51
- Date.new(y,m,d) rescue nil
52
- end
53
- end
46
+ def cast_to_date(val)
47
+ if val.respond_to?(:to_date)
48
+ val.to_date rescue nil
49
+ else
50
+ y, m, d = *[val].flatten
51
+ m ||= 1
52
+ d ||= 1
53
+ Date.new(y,m,d) rescue nil
54
+ end
55
+ end
54
56
 
55
- def cast_to_time(val)
56
- if val.is_a?(Array)
57
- Time.zone.local(*val) rescue nil
58
- else
59
- unless val.acts_like?(:time)
60
- val = val.is_a?(String) ? Time.zone.parse(val) : val.to_time rescue val
61
- end
62
- val.in_time_zone rescue nil
63
- end
64
- end
57
+ def cast_to_time(val)
58
+ if val.is_a?(Array)
59
+ Time.zone.local(*val) rescue nil
60
+ else
61
+ unless val.acts_like?(:time)
62
+ val = val.is_a?(String) ? Time.zone.parse(val) : val.to_time rescue val
63
+ end
64
+ val.in_time_zone rescue nil
65
+ end
66
+ end
65
67
 
66
- def cast_to_boolean(val)
67
- if Constants::TRUE_VALUES.include?(val)
68
- true
69
- elsif Constants::FALSE_VALUES.include?(val)
70
- false
71
- else
72
- nil
73
- end
74
- end
68
+ def cast_to_boolean(val)
69
+ if Constants::TRUE_VALUES.include?(val)
70
+ true
71
+ elsif Constants::FALSE_VALUES.include?(val)
72
+ false
73
+ else
74
+ nil
75
+ end
76
+ end
75
77
 
76
- def cast_to_string(val)
77
- val.respond_to?(:to_s) ? val.to_s : String.new(val)
78
- end
78
+ def cast_to_string(val)
79
+ val.respond_to?(:to_s) ? val.to_s : String.new(val)
80
+ end
79
81
 
80
- def cast_to_integer(val)
81
- val.blank? ? nil : val.to_i
82
- end
82
+ def cast_to_integer(val)
83
+ val.blank? ? nil : val.to_i
84
+ end
83
85
 
84
- def cast_to_float(val)
85
- val.blank? ? nil : val.to_f
86
- end
86
+ def cast_to_float(val)
87
+ val.blank? ? nil : val.to_f
88
+ end
87
89
 
88
- def cast_to_decimal(val)
89
- if val.blank?
90
- nil
91
- elsif val.class == BigDecimal
92
- val
93
- elsif val.respond_to?(:to_d)
94
- val.to_d
95
- else
96
- val.to_s.to_d
97
- end
90
+ def cast_to_decimal(val)
91
+ if val.blank?
92
+ nil
93
+ elsif val.class == BigDecimal
94
+ val
95
+ elsif val.respond_to?(:to_d)
96
+ val.to_d
97
+ else
98
+ val.to_s.to_d
98
99
  end
100
+ end
101
+
102
+ def cast_to_money(val)
103
+ val.blank? ? nil : val.to_f.to_s
104
+ end
99
105
 
100
106
  def inspect
101
107
  "Value <#{value}>"
102
108
  end
103
109
 
104
- def array_of_arrays?(val)
105
- Array === val && Array === val.first
106
- end
110
+ def array_of_arrays?(val)
111
+ Array === val && Array === val.first
112
+ end
107
113
  end
108
114
  end
109
115
  end
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = '1.8.3'
2
+ VERSION = '1.8.4'
3
3
  end
@@ -48,6 +48,7 @@ module Ransack
48
48
  it 'should have default values for arrows' do
49
49
  expect(Ransack.options[:up_arrow]).to eq '&#9660;'
50
50
  expect(Ransack.options[:down_arrow]).to eq '&#9650;'
51
+ expect(Ransack.options[:default_arrow]).to eq nil
51
52
  end
52
53
 
53
54
  it 'changes the default value for the up arrow only' do
@@ -72,17 +73,31 @@ module Ransack
72
73
  Ransack.options = default
73
74
  end
74
75
 
75
- it 'changes the default value for both arrows' do
76
+ it 'changes the default value for the default arrow only' do
77
+ default, new_default_arrow = Ransack.options.clone, '<i class="default"></i>'
78
+
79
+ Ransack.configure { |c| c.custom_arrows = { default_arrow: new_default_arrow } }
80
+
81
+ expect(Ransack.options[:up_arrow]).to eq default[:up_arrow]
82
+ expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
83
+ expect(Ransack.options[:default_arrow]).to eq new_default_arrow
84
+
85
+ Ransack.options = default
86
+ end
87
+
88
+ it 'changes the default value for all arrows' do
76
89
  default = Ransack.options.clone
77
90
  new_up_arrow = '<i class="fa fa-long-arrow-up"></i>'
78
91
  new_down_arrow = 'U+02193'
92
+ new_default_arrow = 'defaultarrow'
79
93
 
80
94
  Ransack.configure do |c|
81
- c.custom_arrows = { up_arrow: new_up_arrow, down_arrow: new_down_arrow }
95
+ c.custom_arrows = { up_arrow: new_up_arrow, down_arrow: new_down_arrow, default_arrow: new_default_arrow }
82
96
  end
83
97
 
84
98
  expect(Ransack.options[:up_arrow]).to eq new_up_arrow
85
99
  expect(Ransack.options[:down_arrow]).to eq new_down_arrow
100
+ expect(Ransack.options[:default_arrow]).to eq new_default_arrow
86
101
 
87
102
  Ransack.options = default
88
103
  end
@@ -727,11 +727,36 @@ module Ransack
727
727
  it { should match /Full Name&nbsp;&#9660;/ }
728
728
  end
729
729
 
730
+ describe '#sort_link with config set to show arrows and a default arrow set' do
731
+ before do
732
+ Ransack.configure do |c|
733
+ c.hide_sort_order_indicators = false
734
+ c.custom_arrows = { default_arrow: "defaultarrow"}
735
+ end
736
+ end
737
+
738
+ after do
739
+ Ransack.configure do |c|
740
+ c.custom_arrows = { default_arrow: nil}
741
+ end
742
+ end
743
+
744
+ subject { @controller.view_context
745
+ .sort_link(
746
+ [:main_app, Person.search],
747
+ :name,
748
+ controller: 'people'
749
+ )
750
+ }
751
+
752
+ it { should match /Full Name&nbsp;defaultarrow/ }
753
+ end
754
+
730
755
  describe '#sort_link w/config to hide arrows + custom arrow, hides all' do
731
756
  before do
732
757
  Ransack.configure do |c|
733
758
  c.hide_sort_order_indicators = true
734
- c.custom_arrows = { down_arrow: 'down' }
759
+ c.custom_arrows = { down_arrow: 'down', default_arrow: "defaultarrow" }
735
760
  end
736
761
  end
737
762
 
@@ -750,7 +775,7 @@ module Ransack
750
775
  )
751
776
  }
752
777
 
753
- it { should_not match /&#9660;|down/ }
778
+ it { should_not match /&#9660;|down|defaultarrow/ }
754
779
  end
755
780
 
756
781
  describe '#sort_link with config set to show arrows + custom arrow' do
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.3
4
+ version: 1.8.4
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: 2017-06-15 00:00:00.000000000 Z
13
+ date: 2017-10-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: actionpack
@@ -241,6 +241,7 @@ files:
241
241
  - lib/ransack/locale/fr.yml
242
242
  - lib/ransack/locale/hu.yml
243
243
  - lib/ransack/locale/id.yml
244
+ - lib/ransack/locale/it.yml
244
245
  - lib/ransack/locale/ja.yml
245
246
  - lib/ransack/locale/nl.yml
246
247
  - lib/ransack/locale/pt-BR.yml
@@ -317,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
318
  version: '0'
318
319
  requirements: []
319
320
  rubyforge_project: ransack
320
- rubygems_version: 2.5.2
321
+ rubygems_version: 2.6.13
321
322
  signing_key:
322
323
  specification_version: 4
323
324
  summary: Object-based searching for Active Record and Mongoid (currently).