ransack 2.4.1 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/cronjob.yml +102 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.github/workflows/test.yml +43 -18
- data/.rubocop.yml +44 -0
- data/CHANGELOG.md +22 -4
- data/CONTRIBUTING.md +6 -5
- data/Gemfile +4 -2
- data/README.md +76 -10
- data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +78 -0
- data/bug_report_templates/test-ransacker-arel-present-predicate.rb +71 -0
- data/docs/img/create_release.png +0 -0
- data/docs/release_process.md +17 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +20 -1
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +11 -1
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +0 -4
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/polyamorous.rb +1 -1
- data/lib/polyamorous.rb +1 -0
- data/lib/ransack/adapters/active_record/base.rb +1 -1
- data/lib/ransack/adapters/active_record/context.rb +9 -5
- data/lib/ransack/adapters/active_record/ransack/constants.rb +1 -1
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +10 -9
- data/lib/ransack/configuration.rb +16 -2
- data/lib/ransack/constants.rb +2 -3
- data/lib/ransack/helpers/form_builder.rb +3 -3
- data/lib/ransack/helpers/form_helper.rb +1 -1
- data/lib/ransack/helpers.rb +1 -1
- data/lib/ransack/locale/sv.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +1 -1
- data/lib/ransack/nodes/condition.rb +0 -2
- data/lib/ransack/nodes/sort.rb +3 -3
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/search.rb +2 -1
- data/lib/ransack/translate.rb +1 -1
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack.rb +2 -2
- data/ransack.gemspec +6 -5
- data/spec/blueprints/articles.rb +1 -1
- data/spec/blueprints/comments.rb +1 -1
- data/spec/blueprints/notes.rb +1 -1
- data/spec/blueprints/tags.rb +1 -1
- data/spec/console.rb +5 -5
- data/spec/helpers/ransack_helper.rb +1 -1
- data/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
- data/spec/polyamorous/join_association_spec.rb +1 -6
- data/spec/polyamorous/join_dependency_spec.rb +0 -16
- data/spec/ransack/adapters/active_record/base_spec.rb +20 -13
- data/spec/ransack/adapters/active_record/context_spec.rb +1 -2
- data/spec/ransack/configuration_spec.rb +14 -0
- data/spec/ransack/helpers/form_helper_spec.rb +17 -18
- data/spec/ransack/nodes/condition_spec.rb +13 -0
- data/spec/ransack/nodes/grouping_spec.rb +2 -2
- data/spec/ransack/predicate_spec.rb +1 -1
- data/spec/ransack/search_spec.rb +117 -27
- data/spec/spec_helper.rb +7 -6
- data/spec/support/schema.rb +33 -2
- metadata +25 -14
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +0 -24
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +0 -79
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +0 -11
@@ -44,12 +44,12 @@ module Ransack
|
|
44
44
|
|
45
45
|
it 'applies stringy boolean scopes with true value in an array' do
|
46
46
|
s = Person.ransack('of_age' => ['true'])
|
47
|
-
expect(s.result.to_sql).to (include 'age >= 18')
|
47
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{(age >= '18')} : 'age >= 18')
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'applies stringy boolean scopes with false value in an array' do
|
51
51
|
s = Person.ransack('of_age' => ['false'])
|
52
|
-
expect(s.result.to_sql).to (include 'age < 18')
|
52
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age < '18'} : 'age < 18')
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'ignores unlisted scopes' do
|
@@ -69,12 +69,12 @@ module Ransack
|
|
69
69
|
|
70
70
|
it 'passes values to scopes' do
|
71
71
|
s = Person.ransack('over_age' => 18)
|
72
|
-
expect(s.result.to_sql).to (include 'age > 18')
|
72
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '18'} : 'age > 18')
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'chains scopes' do
|
76
76
|
s = Person.ransack('over_age' => 18, 'active' => true)
|
77
|
-
expect(s.result.to_sql).to (include 'age > 18')
|
77
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '18'} : 'age > 18')
|
78
78
|
expect(s.result.to_sql).to (include 'active = 1')
|
79
79
|
end
|
80
80
|
|
@@ -89,12 +89,12 @@ module Ransack
|
|
89
89
|
|
90
90
|
it 'passes true values to scopes' do
|
91
91
|
s = Person.ransack('over_age' => 1)
|
92
|
-
expect(s.result.to_sql).to (include 'age > 1')
|
92
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '1'} : 'age > 1')
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'passes false values to scopes' do
|
96
96
|
s = Person.ransack('over_age' => 0)
|
97
|
-
expect(s.result.to_sql).to (include 'age > 0')
|
97
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '0'} : 'age > 0')
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -107,12 +107,12 @@ module Ransack
|
|
107
107
|
|
108
108
|
it 'passes true values to scopes' do
|
109
109
|
s = Person.ransack('over_age' => 1)
|
110
|
-
expect(s.result.to_sql).to (include 'age > 1')
|
110
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '1'} : 'age > 1')
|
111
111
|
end
|
112
112
|
|
113
113
|
it 'passes false values to scopes' do
|
114
114
|
s = Person.ransack('over_age' => 0)
|
115
|
-
expect(s.result.to_sql).to (include 'age > 0')
|
115
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '0'} : 'age > 0')
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -123,7 +123,7 @@ module Ransack
|
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'raises exception if ransack! called with unknown condition' do
|
126
|
-
expect { Person.ransack!(unknown_attr_eq: 'Ernie') }.to raise_error
|
126
|
+
expect { Person.ransack!(unknown_attr_eq: 'Ernie') }.to raise_error(ArgumentError)
|
127
127
|
end
|
128
128
|
|
129
129
|
it 'does not modify the parameters' do
|
@@ -314,7 +314,11 @@ module Ransack
|
|
314
314
|
end
|
315
315
|
|
316
316
|
it 'should function correctly with a multi-parameter attribute' do
|
317
|
-
::ActiveRecord::
|
317
|
+
if ::ActiveRecord::VERSION::MAJOR >= 7
|
318
|
+
::ActiveRecord.default_timezone = :utc
|
319
|
+
else
|
320
|
+
::ActiveRecord::Base.default_timezone = :utc
|
321
|
+
end
|
318
322
|
Time.zone = 'UTC'
|
319
323
|
|
320
324
|
date = Date.current
|
@@ -464,9 +468,9 @@ module Ransack
|
|
464
468
|
Comment.create(article: Article.create(title: 'Avenger'), person: Person.create(salary: 100_000)),
|
465
469
|
Comment.create(article: Article.create(title: 'Avenge'), person: Person.create(salary: 50_000)),
|
466
470
|
]
|
467
|
-
expect(Comment.ransack(article_title_cont: 'aven',s: 'person_salary desc').result).to eq(comments)
|
471
|
+
expect(Comment.ransack(article_title_cont: 'aven', s: 'person_salary desc').result).to eq(comments)
|
468
472
|
expect(Comment.joins(:person).ransack(s: 'persons_salarydesc', article_title_cont: 'aven').result).to eq(comments)
|
469
|
-
expect(Comment.joins(:person).ransack(article_title_cont: 'aven',s: 'persons_salary desc').result).to eq(comments)
|
473
|
+
expect(Comment.joins(:person).ransack(article_title_cont: 'aven', s: 'persons_salary desc').result).to eq(comments)
|
470
474
|
end
|
471
475
|
|
472
476
|
it 'allows sort by `only_sort` field' do
|
@@ -545,7 +549,6 @@ module Ransack
|
|
545
549
|
)
|
546
550
|
end
|
547
551
|
|
548
|
-
|
549
552
|
it 'should allow passing ransacker arguments to a ransacker' do
|
550
553
|
s = Person.ransack(
|
551
554
|
c: [{
|
@@ -691,6 +694,10 @@ module Ransack
|
|
691
694
|
it { should eq [] }
|
692
695
|
end
|
693
696
|
|
697
|
+
private
|
698
|
+
def rails7_and_mysql
|
699
|
+
::ActiveRecord::VERSION::MAJOR >= 7 && ENV['DB'] == 'mysql'
|
700
|
+
end
|
694
701
|
end
|
695
702
|
end
|
696
703
|
end
|
@@ -9,7 +9,6 @@ module Ransack
|
|
9
9
|
describe Context do
|
10
10
|
subject { Context.new(Person) }
|
11
11
|
|
12
|
-
|
13
12
|
it 'has an Active Record alias tracker method' do
|
14
13
|
expect(subject.alias_tracker)
|
15
14
|
.to be_an ::ActiveRecord::Associations::AliasTracker
|
@@ -81,7 +80,7 @@ module Ransack
|
|
81
80
|
end
|
82
81
|
|
83
82
|
it 'build correlated subquery for multiple conditions (default scope)' do
|
84
|
-
search = Search.new(Person, { comments_body_not_eq: 'some_title'})
|
83
|
+
search = Search.new(Person, { comments_body_not_eq: 'some_title' })
|
85
84
|
|
86
85
|
# Was
|
87
86
|
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
@@ -45,6 +45,20 @@ module Ransack
|
|
45
45
|
Ransack.options = default
|
46
46
|
end
|
47
47
|
|
48
|
+
it 'should have default value for strip_whitespace' do
|
49
|
+
expect(Ransack.options[:strip_whitespace]).to eq true
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'changes default search key parameter' do
|
53
|
+
default = Ransack.options.clone
|
54
|
+
|
55
|
+
Ransack.configure { |c| c.strip_whitespace = false }
|
56
|
+
|
57
|
+
expect(Ransack.options[:strip_whitespace]).to eq false
|
58
|
+
|
59
|
+
Ransack.options = default
|
60
|
+
end
|
61
|
+
|
48
62
|
it 'should have default values for arrows' do
|
49
63
|
expect(Ransack.options[:up_arrow]).to eq '▼'
|
50
64
|
expect(Ransack.options[:down_arrow]).to eq '▲'
|
@@ -186,7 +186,7 @@ module Ransack
|
|
186
186
|
)
|
187
187
|
}
|
188
188
|
it {
|
189
|
-
should match(
|
189
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
190
190
|
)
|
191
191
|
}
|
192
192
|
it { should match /sort_link desc/ }
|
@@ -202,7 +202,7 @@ module Ransack
|
|
202
202
|
)
|
203
203
|
}
|
204
204
|
it {
|
205
|
-
should match(
|
205
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
206
206
|
)
|
207
207
|
}
|
208
208
|
end
|
@@ -216,7 +216,7 @@ module Ransack
|
|
216
216
|
)
|
217
217
|
}
|
218
218
|
it {
|
219
|
-
should match(
|
219
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
220
220
|
)
|
221
221
|
}
|
222
222
|
it { should match /sort_link desc/ }
|
@@ -232,7 +232,7 @@ module Ransack
|
|
232
232
|
)
|
233
233
|
}
|
234
234
|
it {
|
235
|
-
should match(
|
235
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
236
236
|
)
|
237
237
|
}
|
238
238
|
end
|
@@ -258,7 +258,7 @@ module Ransack
|
|
258
258
|
)
|
259
259
|
}
|
260
260
|
it {
|
261
|
-
should match(
|
261
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
262
262
|
)
|
263
263
|
}
|
264
264
|
it { should match /sort_link desc/ }
|
@@ -274,7 +274,7 @@ module Ransack
|
|
274
274
|
)
|
275
275
|
}
|
276
276
|
it {
|
277
|
-
should match(
|
277
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
278
278
|
)
|
279
279
|
}
|
280
280
|
end
|
@@ -289,7 +289,7 @@ module Ransack
|
|
289
289
|
)
|
290
290
|
}
|
291
291
|
it {
|
292
|
-
should match(
|
292
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
293
293
|
)
|
294
294
|
}
|
295
295
|
it { should match /sort_link/ }
|
@@ -306,7 +306,7 @@ module Ransack
|
|
306
306
|
)
|
307
307
|
}
|
308
308
|
it {
|
309
|
-
should match(
|
309
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
310
310
|
)
|
311
311
|
}
|
312
312
|
end
|
@@ -321,7 +321,7 @@ module Ransack
|
|
321
321
|
)
|
322
322
|
}
|
323
323
|
it {
|
324
|
-
should match(
|
324
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
325
325
|
)
|
326
326
|
}
|
327
327
|
it { should match /sort_link/ }
|
@@ -338,7 +338,7 @@ module Ransack
|
|
338
338
|
)
|
339
339
|
}
|
340
340
|
it {
|
341
|
-
should match(
|
341
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
342
342
|
)
|
343
343
|
}
|
344
344
|
end
|
@@ -353,7 +353,7 @@ module Ransack
|
|
353
353
|
)
|
354
354
|
}
|
355
355
|
it {
|
356
|
-
should match(
|
356
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
|
357
357
|
)
|
358
358
|
}
|
359
359
|
it { should match /sort_link/ }
|
@@ -370,7 +370,7 @@ module Ransack
|
|
370
370
|
)
|
371
371
|
}
|
372
372
|
it {
|
373
|
-
should match(
|
373
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
|
374
374
|
)
|
375
375
|
}
|
376
376
|
end
|
@@ -385,7 +385,7 @@ module Ransack
|
|
385
385
|
)
|
386
386
|
}
|
387
387
|
it {
|
388
|
-
should match(
|
388
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
389
389
|
)
|
390
390
|
}
|
391
391
|
it { should match /sort_link/ }
|
@@ -402,7 +402,7 @@ module Ransack
|
|
402
402
|
)
|
403
403
|
}
|
404
404
|
it {
|
405
|
-
should match(
|
405
|
+
should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
|
406
406
|
)
|
407
407
|
}
|
408
408
|
end
|
@@ -469,8 +469,7 @@ module Ransack
|
|
469
469
|
it { should match /exist\=existing/ }
|
470
470
|
end
|
471
471
|
|
472
|
-
context 'using a real ActionController::Parameter object'
|
473
|
-
if: ::ActiveRecord::VERSION::MAJOR > 3 do
|
472
|
+
context 'using a real ActionController::Parameter object' do
|
474
473
|
|
475
474
|
describe 'with symbol q:, #sort_link should include search params' do
|
476
475
|
subject { @controller.view_context.sort_link(Person.ransack, :name) }
|
@@ -643,13 +642,13 @@ module Ransack
|
|
643
642
|
before do
|
644
643
|
Ransack.configure do |c|
|
645
644
|
c.hide_sort_order_indicators = false
|
646
|
-
c.custom_arrows = { default_arrow: "defaultarrow"}
|
645
|
+
c.custom_arrows = { default_arrow: "defaultarrow" }
|
647
646
|
end
|
648
647
|
end
|
649
648
|
|
650
649
|
after do
|
651
650
|
Ransack.configure do |c|
|
652
|
-
c.custom_arrows = { default_arrow: nil}
|
651
|
+
c.custom_arrows = { default_arrow: nil }
|
653
652
|
end
|
654
653
|
end
|
655
654
|
|
@@ -3,6 +3,19 @@ require 'spec_helper'
|
|
3
3
|
module Ransack
|
4
4
|
module Nodes
|
5
5
|
describe Condition do
|
6
|
+
context 'bug report #1245' do
|
7
|
+
it 'preserves tuple behavior' do
|
8
|
+
ransack_hash = {
|
9
|
+
m: 'and',
|
10
|
+
g: [
|
11
|
+
{ title_type_in: ['["title 1", ""]'] }
|
12
|
+
]
|
13
|
+
}
|
14
|
+
|
15
|
+
sql = Article.ransack(ransack_hash).result.to_sql
|
16
|
+
expect(sql).to include("IN (('title 1', ''))")
|
17
|
+
end
|
18
|
+
end
|
6
19
|
|
7
20
|
context 'with an alias' do
|
8
21
|
subject {
|
@@ -80,7 +80,7 @@ module Ransack
|
|
80
80
|
'a' => {
|
81
81
|
'0' => {
|
82
82
|
'name' => 'with_arguments',
|
83
|
-
'ransacker_args' => [1,2]
|
83
|
+
'ransacker_args' => [1, 2]
|
84
84
|
}
|
85
85
|
},
|
86
86
|
'p' => 'eq',
|
@@ -90,7 +90,7 @@ module Ransack
|
|
90
90
|
'a' => {
|
91
91
|
'0' => {
|
92
92
|
'name' => 'with_arguments',
|
93
|
-
'ransacker_args' => [3,4]
|
93
|
+
'ransacker_args' => [3, 4]
|
94
94
|
}
|
95
95
|
},
|
96
96
|
'p' => 'eq',
|
@@ -422,7 +422,7 @@ module Ransack
|
|
422
422
|
context "defining custom predicates" do
|
423
423
|
describe "with 'not_in' arel predicate" do
|
424
424
|
before do
|
425
|
-
Ransack.configure {|c| c.add_predicate "not_in_csv", arel_predicate: "not_in", formatter: proc { |v| v.split(",") } }
|
425
|
+
Ransack.configure { |c| c.add_predicate "not_in_csv", arel_predicate: "not_in", formatter: proc { |v| v.split(",") } }
|
426
426
|
end
|
427
427
|
|
428
428
|
it 'generates a value IS NOT NULL query' do
|
data/spec/ransack/search_spec.rb
CHANGED
@@ -20,10 +20,42 @@ module Ransack
|
|
20
20
|
Search.new(Person, name_eq: 'foobar')
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
context 'whitespace stripping' do
|
24
|
+
context 'when whitespace_strip option is true' do
|
25
|
+
before do
|
26
|
+
Ransack.configure { |c| c.strip_whitespace = true }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'strips leading & trailing whitespace before building' do
|
30
|
+
expect_any_instance_of(Search).to receive(:build)
|
31
|
+
.with({ 'name_eq' => 'foobar' })
|
32
|
+
Search.new(Person, name_eq: ' foobar ')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when whitespace_strip option is false' do
|
37
|
+
before do
|
38
|
+
Ransack.configure { |c| c.strip_whitespace = false }
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'doesn\'t strip leading & trailing whitespace before building' do
|
42
|
+
expect_any_instance_of(Search).to receive(:build)
|
43
|
+
.with({ 'name_eq' => ' foobar ' })
|
44
|
+
Search.new(Person, name_eq: ' foobar ')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'strips leading & trailing whitespace when strip_whitespace search parameter is true' do
|
49
|
+
expect_any_instance_of(Search).to receive(:build)
|
50
|
+
.with({ 'name_eq' => 'foobar' })
|
51
|
+
Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: true })
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'doesn\'t strip leading & trailing whitespace when strip_whitespace search parameter is false' do
|
55
|
+
expect_any_instance_of(Search).to receive(:build)
|
56
|
+
.with({ 'name_eq' => ' foobar ' })
|
57
|
+
Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: false })
|
58
|
+
end
|
27
59
|
end
|
28
60
|
|
29
61
|
it 'removes empty suffixed conditions before building' do
|
@@ -300,8 +332,6 @@ module Ransack
|
|
300
332
|
end
|
301
333
|
|
302
334
|
it 'use appropriate table alias' do
|
303
|
-
skip "Rails 6 regressed here, but it's fixed in 6-0-stable since https://github.com/rails/rails/commit/f9ba52477ca288e7effa5f6794ae3df3f4e982bc" if ENV["RAILS"] == "v6.0.3"
|
304
|
-
|
305
335
|
s = Search.new(Person, {
|
306
336
|
name_eq: "person_name_query",
|
307
337
|
articles_title_eq: "person_article_title_query",
|
@@ -451,82 +481,109 @@ module Ransack
|
|
451
481
|
expect(sort.dir).to eq 'asc'
|
452
482
|
end
|
453
483
|
|
454
|
-
it 'creates sorts based on
|
455
|
-
@s.sorts =
|
484
|
+
it 'creates sorts based on a single alias/direction' do
|
485
|
+
@s.sorts = 'daddy desc'
|
486
|
+
expect(@s.sorts.size).to eq(1)
|
487
|
+
sort = @s.sorts.first
|
488
|
+
expect(sort).to be_a Nodes::Sort
|
489
|
+
expect(sort.name).to eq 'parent_name'
|
490
|
+
expect(sort.dir).to eq 'desc'
|
491
|
+
end
|
492
|
+
|
493
|
+
it 'creates sorts based on a single alias and uppercase direction' do
|
494
|
+
@s.sorts = 'daddy DESC'
|
495
|
+
expect(@s.sorts.size).to eq(1)
|
496
|
+
sort = @s.sorts.first
|
497
|
+
expect(sort).to be_a Nodes::Sort
|
498
|
+
expect(sort.name).to eq 'parent_name'
|
499
|
+
expect(sort.dir).to eq 'desc'
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'creates sorts based on a single alias and without direction' do
|
503
|
+
@s.sorts = 'daddy'
|
504
|
+
expect(@s.sorts.size).to eq(1)
|
505
|
+
sort = @s.sorts.first
|
506
|
+
expect(sort).to be_a Nodes::Sort
|
507
|
+
expect(sort.name).to eq 'parent_name'
|
508
|
+
expect(sort.dir).to eq 'asc'
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'creates sorts based on attributes, alias and directions in array format' do
|
512
|
+
@s.sorts = ['id desc', { name: 'daddy', dir: 'asc' }]
|
456
513
|
expect(@s.sorts.size).to eq(2)
|
457
514
|
sort1, sort2 = @s.sorts
|
458
515
|
expect(sort1).to be_a Nodes::Sort
|
459
516
|
expect(sort1.name).to eq 'id'
|
460
517
|
expect(sort1.dir).to eq 'desc'
|
461
518
|
expect(sort2).to be_a Nodes::Sort
|
462
|
-
expect(sort2.name).to eq '
|
519
|
+
expect(sort2.name).to eq 'parent_name'
|
463
520
|
expect(sort2.dir).to eq 'asc'
|
464
521
|
end
|
465
522
|
|
466
|
-
it 'creates sorts based on
|
467
|
-
@s.sorts = ['id DESC', { name: '
|
523
|
+
it 'creates sorts based on attributes, alias and uppercase directions in array format' do
|
524
|
+
@s.sorts = ['id DESC', { name: 'daddy', dir: 'ASC' }]
|
468
525
|
expect(@s.sorts.size).to eq(2)
|
469
526
|
sort1, sort2 = @s.sorts
|
470
527
|
expect(sort1).to be_a Nodes::Sort
|
471
528
|
expect(sort1.name).to eq 'id'
|
472
529
|
expect(sort1.dir).to eq 'desc'
|
473
530
|
expect(sort2).to be_a Nodes::Sort
|
474
|
-
expect(sort2.name).to eq '
|
531
|
+
expect(sort2.name).to eq 'parent_name'
|
475
532
|
expect(sort2.dir).to eq 'asc'
|
476
533
|
end
|
477
534
|
|
478
|
-
it 'creates sorts based on
|
535
|
+
it 'creates sorts based on attributes, alias and different directions
|
479
536
|
in array format' do
|
480
|
-
@s.sorts = ['id DESC', { name: '
|
537
|
+
@s.sorts = ['id DESC', { name: 'daddy', dir: nil }]
|
481
538
|
expect(@s.sorts.size).to eq(2)
|
482
539
|
sort1, sort2 = @s.sorts
|
483
540
|
expect(sort1).to be_a Nodes::Sort
|
484
541
|
expect(sort1.name).to eq 'id'
|
485
542
|
expect(sort1.dir).to eq 'desc'
|
486
543
|
expect(sort2).to be_a Nodes::Sort
|
487
|
-
expect(sort2.name).to eq '
|
544
|
+
expect(sort2.name).to eq 'parent_name'
|
488
545
|
expect(sort2.dir).to eq 'asc'
|
489
546
|
end
|
490
547
|
|
491
|
-
it 'creates sorts based on
|
548
|
+
it 'creates sorts based on attributes, alias and directions in hash format' do
|
492
549
|
@s.sorts = {
|
493
550
|
'0' => { name: 'id', dir: 'desc' },
|
494
|
-
'1' => { name: '
|
551
|
+
'1' => { name: 'daddy', dir: 'asc' }
|
495
552
|
}
|
496
553
|
expect(@s.sorts.size).to eq(2)
|
497
554
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
498
555
|
id_sort = @s.sorts.detect { |s| s.name == 'id' }
|
499
|
-
|
556
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
500
557
|
expect(id_sort.dir).to eq 'desc'
|
501
|
-
expect(
|
558
|
+
expect(daddy_sort.dir).to eq 'asc'
|
502
559
|
end
|
503
560
|
|
504
|
-
it 'creates sorts based on
|
561
|
+
it 'creates sorts based on attributes, alias and uppercase directions
|
505
562
|
in hash format' do
|
506
563
|
@s.sorts = {
|
507
564
|
'0' => { name: 'id', dir: 'DESC' },
|
508
|
-
'1' => { name: '
|
565
|
+
'1' => { name: 'daddy', dir: 'ASC' }
|
509
566
|
}
|
510
567
|
expect(@s.sorts.size).to eq(2)
|
511
568
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
512
569
|
id_sort = @s.sorts.detect { |s| s.name == 'id' }
|
513
|
-
|
570
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
514
571
|
expect(id_sort.dir).to eq 'desc'
|
515
|
-
expect(
|
572
|
+
expect(daddy_sort.dir).to eq 'asc'
|
516
573
|
end
|
517
574
|
|
518
|
-
it 'creates sorts based on
|
575
|
+
it 'creates sorts based on attributes, alias and different directions
|
519
576
|
in hash format' do
|
520
577
|
@s.sorts = {
|
521
578
|
'0' => { name: 'id', dir: 'DESC' },
|
522
|
-
'1' => { name: '
|
579
|
+
'1' => { name: 'daddy', dir: nil }
|
523
580
|
}
|
524
581
|
expect(@s.sorts.size).to eq(2)
|
525
582
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
526
583
|
id_sort = @s.sorts.detect { |s| s.name == 'id' }
|
527
|
-
|
584
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
528
585
|
expect(id_sort.dir).to eq 'desc'
|
529
|
-
expect(
|
586
|
+
expect(daddy_sort.dir).to eq 'asc'
|
530
587
|
end
|
531
588
|
|
532
589
|
it 'overrides existing sort' do
|
@@ -554,6 +611,39 @@ module Ransack
|
|
554
611
|
|
555
612
|
Ransack.options = default
|
556
613
|
end
|
614
|
+
|
615
|
+
it "PG's sort option with double name", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
|
616
|
+
default = Ransack.options.clone
|
617
|
+
|
618
|
+
s = Search.new(Person, s: 'doubled_name asc')
|
619
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC"
|
620
|
+
|
621
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
|
622
|
+
s = Search.new(Person, s: 'doubled_name asc')
|
623
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS FIRST"
|
624
|
+
s = Search.new(Person, s: 'doubled_name desc')
|
625
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS LAST"
|
626
|
+
|
627
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_last }
|
628
|
+
s = Search.new(Person, s: 'doubled_name asc')
|
629
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS LAST"
|
630
|
+
s = Search.new(Person, s: 'doubled_name desc')
|
631
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS FIRST"
|
632
|
+
|
633
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_always_first }
|
634
|
+
s = Search.new(Person, s: 'doubled_name asc')
|
635
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS FIRST"
|
636
|
+
s = Search.new(Person, s: 'doubled_name desc')
|
637
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS FIRST"
|
638
|
+
|
639
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_always_last }
|
640
|
+
s = Search.new(Person, s: 'doubled_name asc')
|
641
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS LAST"
|
642
|
+
s = Search.new(Person, s: 'doubled_name desc')
|
643
|
+
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS LAST"
|
644
|
+
|
645
|
+
Ransack.options = default
|
646
|
+
end
|
557
647
|
end
|
558
648
|
|
559
649
|
describe '#method_missing' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'machinist/active_record'
|
2
|
-
require 'polyamorous/polyamorous
|
2
|
+
require 'polyamorous/polyamorous'
|
3
3
|
require 'sham'
|
4
4
|
require 'faker'
|
5
5
|
require 'ransack'
|
@@ -17,16 +17,17 @@ I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'support', '*.yml')]
|
|
17
17
|
Dir[File.expand_path('../{helpers,support,blueprints}/*.rb', __FILE__)]
|
18
18
|
.each { |f| require f }
|
19
19
|
|
20
|
+
Faker::Config.random = Random.new(0)
|
20
21
|
Sham.define do
|
21
22
|
name { Faker::Name.name }
|
22
23
|
title { Faker::Lorem.sentence }
|
23
24
|
body { Faker::Lorem.paragraph }
|
24
25
|
salary { |index| 30000 + (index * 1000) }
|
25
|
-
tag_name { Faker::Lorem.words(3).join(' ') }
|
26
|
-
note { Faker::Lorem.words(7).join(' ') }
|
27
|
-
only_admin { Faker::Lorem.words(3).join(' ') }
|
28
|
-
only_search { Faker::Lorem.words(3).join(' ') }
|
29
|
-
only_sort { Faker::Lorem.words(3).join(' ') }
|
26
|
+
tag_name { Faker::Lorem.words(number: 3).join(' ') }
|
27
|
+
note { Faker::Lorem.words(number: 7).join(' ') }
|
28
|
+
only_admin { Faker::Lorem.words(number: 3).join(' ') }
|
29
|
+
only_search { Faker::Lorem.words(number: 3).join(' ') }
|
30
|
+
only_sort { Faker::Lorem.words(number: 3).join(' ') }
|
30
31
|
notable_id { |id| id }
|
31
32
|
end
|
32
33
|
|