ransack 1.8.3 → 1.8.4

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 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).