ransack 2.4.1 → 2.6.0
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 +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
|
|