ransack 1.6.4 → 1.6.5
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/.travis.yml +1 -11
- data/CHANGELOG.md +50 -10
- data/CONTRIBUTING.md +29 -18
- data/README.md +9 -31
- data/lib/ransack/adapters/active_record/context.rb +22 -17
- data/lib/ransack/adapters/active_record/ransack/context.rb +1 -1
- data/lib/ransack/predicate.rb +2 -2
- data/lib/ransack/translate.rb +0 -5
- data/lib/ransack/version.rb +1 -1
- data/spec/mongoid/configuration_spec.rb +36 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +7 -6
- data/spec/ransack/configuration_spec.rb +36 -0
- data/spec/ransack/helpers/form_helper_spec.rb +65 -58
- data/spec/ransack/search_spec.rb +134 -104
- data/spec/spec_helper.rb +3 -4
- data/spec/support/schema.rb +36 -23
- metadata +2 -2
@@ -64,5 +64,41 @@ module Ransack
|
|
64
64
|
expect(Ransack.predicates).not_to have_key 'test_array_predicate_any'
|
65
65
|
expect(Ransack.predicates).not_to have_key 'test_array_predicate_all'
|
66
66
|
end
|
67
|
+
|
68
|
+
describe '`wants_array` option takes precedence over Arel predicate' do
|
69
|
+
it 'implicitly wants an array for in/not in predicates' do
|
70
|
+
Ransack.configure do |config|
|
71
|
+
config.add_predicate(
|
72
|
+
:test_in_predicate,
|
73
|
+
:arel_predicate => 'in'
|
74
|
+
)
|
75
|
+
config.add_predicate(
|
76
|
+
:test_not_in_predicate,
|
77
|
+
:arel_predicate => 'not_in'
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
expect(Ransack.predicates['test_in_predicate'].wants_array).to eq true
|
82
|
+
expect(Ransack.predicates['test_not_in_predicate'].wants_array).to eq true
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'explicitly does not want array for in/not_in predicates' do
|
86
|
+
Ransack.configure do |config|
|
87
|
+
config.add_predicate(
|
88
|
+
:test_in_predicate_no_array,
|
89
|
+
:arel_predicate => 'in',
|
90
|
+
:wants_array => false
|
91
|
+
)
|
92
|
+
config.add_predicate(
|
93
|
+
:test_not_in_predicate_no_array,
|
94
|
+
:arel_predicate => 'not_in',
|
95
|
+
:wants_array => false
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array).to eq false
|
100
|
+
expect(Ransack.predicates['test_not_in_predicate_no_array'].wants_array).to eq false
|
101
|
+
end
|
102
|
+
end
|
67
103
|
end
|
68
104
|
end
|
@@ -31,9 +31,9 @@ module Ransack
|
|
31
31
|
describe '#sort_link with default search_key' do
|
32
32
|
subject { @controller.view_context
|
33
33
|
.sort_link(
|
34
|
-
[:main_app, Person.search(:
|
34
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
35
35
|
:name,
|
36
|
-
:
|
36
|
+
controller: 'people'
|
37
37
|
)
|
38
38
|
}
|
39
39
|
it {
|
@@ -53,10 +53,10 @@ module Ransack
|
|
53
53
|
subject { @controller.view_context
|
54
54
|
.sort_link(
|
55
55
|
Person.search(
|
56
|
-
{ :
|
56
|
+
{ sorts: ['name desc'] }, search_key: :people_search
|
57
57
|
),
|
58
58
|
:name,
|
59
|
-
:
|
59
|
+
controller: 'people'
|
60
60
|
)
|
61
61
|
}
|
62
62
|
it {
|
@@ -73,10 +73,11 @@ module Ransack
|
|
73
73
|
describe '#sort_link desc through association table defined as a symbol' do
|
74
74
|
subject { @controller.view_context
|
75
75
|
.sort_link(
|
76
|
-
Person.search({ :
|
77
|
-
:comments_body,
|
78
|
-
|
79
|
-
|
76
|
+
Person.search({ sorts: 'comments_body asc' }),
|
77
|
+
:comments_body,
|
78
|
+
controller: 'people'
|
79
|
+
)
|
80
|
+
}
|
80
81
|
it {
|
81
82
|
should match(
|
82
83
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
@@ -93,10 +94,11 @@ module Ransack
|
|
93
94
|
describe '#sort_link through association table defined as a string' do
|
94
95
|
subject { @controller.view_context
|
95
96
|
.sort_link(
|
96
|
-
Person.search({ :
|
97
|
-
'comments.body',
|
98
|
-
|
99
|
-
|
97
|
+
Person.search({ sorts: 'comments.body desc' }),
|
98
|
+
'comments.body',
|
99
|
+
controller: 'people'
|
100
|
+
)
|
101
|
+
}
|
100
102
|
it {
|
101
103
|
should match(
|
102
104
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
@@ -113,24 +115,25 @@ module Ransack
|
|
113
115
|
describe '#sort_link works even if search params are a blank string' do
|
114
116
|
before { @controller.view_context.params[:q] = '' }
|
115
117
|
specify {
|
116
|
-
expect {
|
117
|
-
|
118
|
-
Person.search(
|
119
|
-
|
120
|
-
|
121
|
-
|
118
|
+
expect { @controller.view_context
|
119
|
+
.sort_link(
|
120
|
+
Person.search(
|
121
|
+
@controller.view_context.params[:q]),
|
122
|
+
:name,
|
123
|
+
controller: 'people'
|
124
|
+
)
|
122
125
|
}.not_to raise_error
|
123
126
|
}
|
124
127
|
end
|
125
128
|
|
126
129
|
describe '#sort_link with search_key defined as a string' do
|
127
|
-
subject {
|
128
|
-
|
130
|
+
subject { @controller.view_context
|
131
|
+
.sort_link(
|
129
132
|
Person.search(
|
130
|
-
{ :
|
131
|
-
|
133
|
+
{ sorts: ['name desc'] }, search_key: 'people_search'
|
134
|
+
),
|
132
135
|
:name,
|
133
|
-
:
|
136
|
+
controller: 'people'
|
134
137
|
)
|
135
138
|
}
|
136
139
|
it {
|
@@ -149,8 +152,8 @@ module Ransack
|
|
149
152
|
.sort_link(
|
150
153
|
[:main_app, Person.search()],
|
151
154
|
:name,
|
152
|
-
:
|
153
|
-
|
155
|
+
controller: 'people',
|
156
|
+
default_order: 'desc'
|
154
157
|
)
|
155
158
|
}
|
156
159
|
it { should_not match /default_order/ }
|
@@ -159,9 +162,9 @@ module Ransack
|
|
159
162
|
describe '#sort_link with multiple search_keys defined as an array' do
|
160
163
|
subject { @controller.view_context
|
161
164
|
.sort_link(
|
162
|
-
[:main_app, Person.search(:
|
165
|
+
[:main_app, Person.search(sorts: ['name desc', 'email asc'])],
|
163
166
|
:name, [:name, 'email DESC'],
|
164
|
-
:
|
167
|
+
controller: 'people'
|
165
168
|
)
|
166
169
|
}
|
167
170
|
it {
|
@@ -176,9 +179,9 @@ module Ransack
|
|
176
179
|
describe '#sort_link with multiple search_keys does not break on nil values & ignores them' do
|
177
180
|
subject { @controller.view_context
|
178
181
|
.sort_link(
|
179
|
-
[:main_app, Person.search(:
|
182
|
+
[:main_app, Person.search(sorts: ['name desc', nil, 'email', nil])],
|
180
183
|
:name, [nil, :name, nil, 'email DESC', nil],
|
181
|
-
:
|
184
|
+
controller: 'people'
|
182
185
|
)
|
183
186
|
}
|
184
187
|
it {
|
@@ -193,10 +196,10 @@ module Ransack
|
|
193
196
|
describe '#sort_link with multiple search_keys should allow a label to be specified' do
|
194
197
|
subject { @controller.view_context
|
195
198
|
.sort_link(
|
196
|
-
[:main_app, Person.search(:
|
199
|
+
[:main_app, Person.search(sorts: ['name desc', 'email asc'])],
|
197
200
|
:name, [:name, 'email DESC'],
|
198
201
|
'Property Name',
|
199
|
-
:
|
202
|
+
controller: 'people'
|
200
203
|
)
|
201
204
|
}
|
202
205
|
it { should match /Property Name ▼/ }
|
@@ -205,9 +208,9 @@ module Ransack
|
|
205
208
|
describe '#sort_link with multiple search_keys should flip multiple fields specified without a direction' do
|
206
209
|
subject { @controller.view_context
|
207
210
|
.sort_link(
|
208
|
-
[:main_app, Person.search(:
|
211
|
+
[:main_app, Person.search(sorts: ['name desc', 'email asc'])],
|
209
212
|
:name, [:name, :email],
|
210
|
-
:
|
213
|
+
controller: 'people'
|
211
214
|
)
|
212
215
|
}
|
213
216
|
it {
|
@@ -224,8 +227,8 @@ module Ransack
|
|
224
227
|
.sort_link(
|
225
228
|
[:main_app, Person.search()],
|
226
229
|
:name, [:name, :email],
|
227
|
-
:
|
228
|
-
|
230
|
+
controller: 'people',
|
231
|
+
default_order: 'desc'
|
229
232
|
)
|
230
233
|
}
|
231
234
|
it {
|
@@ -242,8 +245,8 @@ module Ransack
|
|
242
245
|
.sort_link(
|
243
246
|
[:main_app, Person.search()],
|
244
247
|
:name, [:name, :email],
|
245
|
-
:
|
246
|
-
:
|
248
|
+
controller: 'people',
|
249
|
+
default_order: :desc
|
247
250
|
)
|
248
251
|
}
|
249
252
|
it {
|
@@ -260,8 +263,8 @@ module Ransack
|
|
260
263
|
.sort_link(
|
261
264
|
[:main_app, Person.search()],
|
262
265
|
:name, [:name, :email],
|
263
|
-
:
|
264
|
-
:
|
266
|
+
controller: 'people',
|
267
|
+
default_order: { name: 'desc', email: 'asc' }
|
265
268
|
)
|
266
269
|
}
|
267
270
|
it {
|
@@ -278,8 +281,8 @@ module Ransack
|
|
278
281
|
.sort_link(
|
279
282
|
[:main_app, Person.search()],
|
280
283
|
:name, [:name, 'email desc'],
|
281
|
-
:
|
282
|
-
:
|
284
|
+
controller: 'people',
|
285
|
+
default_order: { name: 'desc', email: 'asc' }
|
283
286
|
)
|
284
287
|
}
|
285
288
|
it {
|
@@ -295,7 +298,8 @@ module Ransack
|
|
295
298
|
subject { @controller.view_context
|
296
299
|
.sort_link(
|
297
300
|
[:main_app, Note.search()],
|
298
|
-
:notable_of_Person_type_name, "Notable",
|
301
|
+
:notable_of_Person_type_name, "Notable",
|
302
|
+
controller: 'notes'
|
299
303
|
)
|
300
304
|
}
|
301
305
|
it {
|
@@ -313,16 +317,17 @@ module Ransack
|
|
313
317
|
|
314
318
|
context 'view has existing parameters' do
|
315
319
|
before do
|
316
|
-
@controller.view_context.params.merge!({ :
|
320
|
+
@controller.view_context.params.merge!({ exist: 'existing' })
|
317
321
|
end
|
318
322
|
describe '#sort_link should not remove existing params' do
|
319
|
-
subject {
|
320
|
-
|
323
|
+
subject { @controller.view_context
|
324
|
+
.sort_link(
|
321
325
|
Person.search(
|
322
|
-
{ :
|
323
|
-
|
326
|
+
{ sorts: ['name desc'] },
|
327
|
+
search_key: 'people_search'
|
328
|
+
),
|
324
329
|
:name,
|
325
|
-
:
|
330
|
+
controller: 'people'
|
326
331
|
)
|
327
332
|
}
|
328
333
|
it { should match /exist\=existing/ }
|
@@ -332,10 +337,10 @@ module Ransack
|
|
332
337
|
describe '#sort_link with hide order indicator set to true' do
|
333
338
|
subject { @controller.view_context
|
334
339
|
.sort_link(
|
335
|
-
[:main_app, Person.search(:
|
340
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
336
341
|
:name,
|
337
|
-
:
|
338
|
-
:
|
342
|
+
controller: 'people',
|
343
|
+
hide_indicator: true
|
339
344
|
)
|
340
345
|
}
|
341
346
|
it { should match /Full Name/ }
|
@@ -344,24 +349,25 @@ module Ransack
|
|
344
349
|
describe '#sort_link with hide order indicator set to false' do
|
345
350
|
subject { @controller.view_context
|
346
351
|
.sort_link(
|
347
|
-
[:main_app, Person.search(:
|
352
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
348
353
|
:name,
|
349
|
-
:
|
350
|
-
:
|
354
|
+
controller: 'people',
|
355
|
+
hide_indicator: false
|
351
356
|
)
|
352
357
|
}
|
353
358
|
it { should match /Full Name ▼/ }
|
354
359
|
end
|
355
360
|
|
356
361
|
describe '#search_form_for with default format' do
|
357
|
-
subject { @controller.view_context
|
362
|
+
subject { @controller.view_context
|
363
|
+
.search_form_for(Person.search) {} }
|
358
364
|
it { should match /action="\/people"/ }
|
359
365
|
end
|
360
366
|
|
361
367
|
describe '#search_form_for with pdf format' do
|
362
368
|
subject {
|
363
369
|
@controller.view_context
|
364
|
-
.search_form_for(Person.search, :
|
370
|
+
.search_form_for(Person.search, format: :pdf) {}
|
365
371
|
}
|
366
372
|
it { should match /action="\/people.pdf"/ }
|
367
373
|
end
|
@@ -369,14 +375,15 @@ module Ransack
|
|
369
375
|
describe '#search_form_for with json format' do
|
370
376
|
subject {
|
371
377
|
@controller.view_context
|
372
|
-
.search_form_for(Person.search, :
|
378
|
+
.search_form_for(Person.search, format: :json) {}
|
373
379
|
}
|
374
380
|
it { should match /action="\/people.json"/ }
|
375
381
|
end
|
376
382
|
|
377
383
|
describe '#search_form_for with an array of routes' do
|
378
384
|
subject {
|
379
|
-
@controller.view_context
|
385
|
+
@controller.view_context
|
386
|
+
.search_form_for([:admin, Comment.search]) {}
|
380
387
|
}
|
381
388
|
it { should match /action="\/admin\/comments"/ }
|
382
389
|
end
|
data/spec/ransack/search_spec.rb
CHANGED
@@ -3,38 +3,38 @@ require 'spec_helper'
|
|
3
3
|
module Ransack
|
4
4
|
describe Search do
|
5
5
|
describe '#initialize' do
|
6
|
-
it
|
6
|
+
it 'removes empty conditions before building' do
|
7
7
|
expect_any_instance_of(Search).to receive(:build).with({})
|
8
|
-
Search.new(Person, :
|
8
|
+
Search.new(Person, name_eq: '')
|
9
9
|
end
|
10
10
|
|
11
|
-
it
|
11
|
+
it 'keeps conditions with a false value before building' do
|
12
12
|
expect_any_instance_of(Search).to receive(:build)
|
13
|
-
.with({
|
14
|
-
Search.new(Person, :
|
13
|
+
.with({ 'name_eq' => false })
|
14
|
+
Search.new(Person, name_eq: false)
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
17
|
+
it 'keeps conditions with a value before building' do
|
18
18
|
expect_any_instance_of(Search).to receive(:build)
|
19
|
-
.with({
|
20
|
-
Search.new(Person, :
|
19
|
+
.with({ 'name_eq' => 'foobar' })
|
20
|
+
Search.new(Person, name_eq: 'foobar')
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it 'removes empty suffixed conditions before building' do
|
24
24
|
expect_any_instance_of(Search).to receive(:build).with({})
|
25
|
-
Search.new(Person, :
|
25
|
+
Search.new(Person, name_eq_any: [''])
|
26
26
|
end
|
27
27
|
|
28
|
-
it
|
28
|
+
it 'keeps suffixed conditions with a false value before building' do
|
29
29
|
expect_any_instance_of(Search).to receive(:build)
|
30
|
-
.with({
|
31
|
-
Search.new(Person, :
|
30
|
+
.with({ 'name_eq_any' => [false] })
|
31
|
+
Search.new(Person, name_eq_any: [false])
|
32
32
|
end
|
33
33
|
|
34
|
-
it
|
34
|
+
it 'keeps suffixed conditions with a value before building' do
|
35
35
|
expect_any_instance_of(Search).to receive(:build)
|
36
|
-
.with({
|
37
|
-
Search.new(Person, :
|
36
|
+
.with({ 'name_eq_any' => ['foobar'] })
|
37
|
+
Search.new(Person, name_eq_any: ['foobar'])
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'does not raise exception for string :params argument' do
|
@@ -43,19 +43,15 @@ module Ransack
|
|
43
43
|
|
44
44
|
it 'accepts a context option' do
|
45
45
|
shared_context = Context.for(Person)
|
46
|
-
search1 = Search.new(
|
47
|
-
|
48
|
-
)
|
49
|
-
search2 = Search.new(
|
50
|
-
Person, { "name_eq" => "B" }, context: shared_context
|
51
|
-
)
|
46
|
+
search1 = Search.new(Person, { name_eq: 'A' }, context: shared_context)
|
47
|
+
search2 = Search.new(Person, { name_eq: 'B' }, context: shared_context)
|
52
48
|
expect(search1.context).to be search2.context
|
53
49
|
end
|
54
50
|
end
|
55
51
|
|
56
52
|
describe '#build' do
|
57
53
|
it 'creates conditions for top-level attributes' do
|
58
|
-
search = Search.new(Person, :
|
54
|
+
search = Search.new(Person, name_eq: 'Ernie')
|
59
55
|
condition = search.base[:name_eq]
|
60
56
|
expect(condition).to be_a Nodes::Condition
|
61
57
|
expect(condition.predicate.name).to eq 'eq'
|
@@ -64,7 +60,7 @@ module Ransack
|
|
64
60
|
end
|
65
61
|
|
66
62
|
it 'creates conditions for association attributes' do
|
67
|
-
search = Search.new(Person, :
|
63
|
+
search = Search.new(Person, children_name_eq: 'Ernie')
|
68
64
|
condition = search.base[:children_name_eq]
|
69
65
|
expect(condition).to be_a Nodes::Condition
|
70
66
|
expect(condition.predicate.name).to eq 'eq'
|
@@ -73,33 +69,37 @@ module Ransack
|
|
73
69
|
end
|
74
70
|
|
75
71
|
it 'creates conditions for polymorphic belongs_to association attributes' do
|
76
|
-
search = Search.new(Note, :
|
72
|
+
search = Search.new(Note, notable_of_Person_type_name_eq: 'Ernie')
|
77
73
|
condition = search.base[:notable_of_Person_type_name_eq]
|
78
74
|
expect(condition).to be_a Nodes::Condition
|
79
75
|
expect(condition.predicate.name).to eq 'eq'
|
80
|
-
expect(condition.attributes.first.name)
|
76
|
+
expect(condition.attributes.first.name)
|
77
|
+
.to eq 'notable_of_Person_type_name'
|
81
78
|
expect(condition.value).to eq 'Ernie'
|
82
79
|
end
|
83
80
|
|
84
|
-
it 'creates conditions for multiple polymorphic belongs_to association
|
81
|
+
it 'creates conditions for multiple polymorphic belongs_to association
|
82
|
+
attributes' do
|
85
83
|
search = Search.new(Note,
|
86
|
-
:
|
84
|
+
notable_of_Person_type_name_or_notable_of_Article_type_title_eq: 'Ernie')
|
87
85
|
condition = search.
|
88
86
|
base[:notable_of_Person_type_name_or_notable_of_Article_type_title_eq]
|
89
87
|
expect(condition).to be_a Nodes::Condition
|
90
88
|
expect(condition.predicate.name).to eq 'eq'
|
91
|
-
expect(condition.attributes.first.name)
|
92
|
-
|
89
|
+
expect(condition.attributes.first.name)
|
90
|
+
.to eq 'notable_of_Person_type_name'
|
91
|
+
expect(condition.attributes.last.name)
|
92
|
+
.to eq 'notable_of_Article_type_title'
|
93
93
|
expect(condition.value).to eq 'Ernie'
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'preserves default scope conditions for associations' do
|
97
|
-
search = Search.new(Person, :
|
98
|
-
expect(search.result.to_sql).to include
|
97
|
+
search = Search.new(Person, articles_title_eq: 'Test')
|
98
|
+
expect(search.result.to_sql).to include 'default_scope'
|
99
99
|
end
|
100
100
|
|
101
101
|
it 'discards empty conditions' do
|
102
|
-
search = Search.new(Person, :
|
102
|
+
search = Search.new(Person, children_name_eq: '')
|
103
103
|
condition = search.base[:children_name_eq]
|
104
104
|
expect(condition).to be_nil
|
105
105
|
end
|
@@ -112,8 +112,8 @@ module Ransack
|
|
112
112
|
it 'accepts arrays of groupings' do
|
113
113
|
search = Search.new(Person,
|
114
114
|
g: [
|
115
|
-
{ :
|
116
|
-
{ :
|
115
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' },
|
116
|
+
{ m: 'or', name_eq: 'Bert', children_name_eq: 'Bert' },
|
117
117
|
]
|
118
118
|
)
|
119
119
|
ors = search.groupings
|
@@ -143,11 +143,13 @@ module Ransack
|
|
143
143
|
|
144
144
|
it 'accepts "attributes" hashes for conditions' do
|
145
145
|
search = Search.new(Person,
|
146
|
-
:
|
147
|
-
'0' => { :
|
148
|
-
'1' => {
|
149
|
-
:
|
150
|
-
|
146
|
+
c: {
|
147
|
+
'0' => { a: ['name'], p: 'eq', v: ['Ernie'] },
|
148
|
+
'1' => {
|
149
|
+
a: ['children_name', 'parent_name'],
|
150
|
+
p: 'eq', v: ['Ernie'], m: 'or'
|
151
|
+
}
|
152
|
+
}
|
151
153
|
)
|
152
154
|
conditions = search.base.conditions
|
153
155
|
expect(conditions.size).to eq(2)
|
@@ -157,10 +159,10 @@ module Ransack
|
|
157
159
|
|
158
160
|
it 'creates conditions for custom predicates that take arrays' do
|
159
161
|
Ransack.configure do |config|
|
160
|
-
config.add_predicate 'ary_pred', :
|
162
|
+
config.add_predicate 'ary_pred', wants_array: true
|
161
163
|
end
|
162
164
|
|
163
|
-
search = Search.new(Person, :
|
165
|
+
search = Search.new(Person, name_ary_pred: ['Ernie', 'Bert'])
|
164
166
|
condition = search.base[:name_ary_pred]
|
165
167
|
expect(condition).to be_a Nodes::Condition
|
166
168
|
expect(condition.predicate.name).to eq 'ary_pred'
|
@@ -169,14 +171,14 @@ module Ransack
|
|
169
171
|
end
|
170
172
|
|
171
173
|
it 'does not evaluate the query on #inspect' do
|
172
|
-
search = Search.new(Person, :
|
174
|
+
search = Search.new(Person, children_id_in: [1, 2, 3])
|
173
175
|
expect(search.inspect).not_to match /ActiveRecord/
|
174
176
|
end
|
175
177
|
|
176
178
|
context 'with an invalid condition' do
|
177
|
-
subject { Search.new(Person, :
|
179
|
+
subject { Search.new(Person, unknown_attr_eq: 'Ernie') }
|
178
180
|
|
179
|
-
context
|
181
|
+
context 'when ignore_unknown_conditions is false' do
|
180
182
|
before do
|
181
183
|
Ransack.configure { |c| c.ignore_unknown_conditions = false }
|
182
184
|
end
|
@@ -184,7 +186,7 @@ module Ransack
|
|
184
186
|
specify { expect { subject }.to raise_error ArgumentError }
|
185
187
|
end
|
186
188
|
|
187
|
-
context
|
189
|
+
context 'when ignore_unknown_conditions is true' do
|
188
190
|
before do
|
189
191
|
Ransack.configure { |c| c.ignore_unknown_conditions = true }
|
190
192
|
end
|
@@ -194,7 +196,7 @@ module Ransack
|
|
194
196
|
end
|
195
197
|
|
196
198
|
it 'does not modify the parameters' do
|
197
|
-
params = { :
|
199
|
+
params = { name_eq: '' }
|
198
200
|
expect { Search.new(Person, params) }.not_to change { params }
|
199
201
|
end
|
200
202
|
|
@@ -208,68 +210,87 @@ module Ransack
|
|
208
210
|
"#{quote_table_name("children_people")}.#{quote_column_name("name")}"
|
209
211
|
}
|
210
212
|
it 'evaluates conditions contextually' do
|
211
|
-
search = Search.new(Person, :
|
213
|
+
search = Search.new(Person, children_name_eq: 'Ernie')
|
212
214
|
expect(search.result).to be_an ActiveRecord::Relation
|
213
|
-
|
214
|
-
|
215
|
+
expect(search.result.to_sql).to match /#{
|
216
|
+
children_people_name_field} = 'Ernie'/
|
217
|
+
end
|
218
|
+
|
219
|
+
# FIXME: Make this spec pass for Rails 4.1 / 4.2 / 5.0 and not just 4.0 by
|
220
|
+
# commenting out lines 221 and 242 to run the test. Addresses issue #374.
|
221
|
+
# https://github.com/activerecord-hackery/ransack/issues/374
|
222
|
+
#
|
223
|
+
if ::ActiveRecord::VERSION::STRING.first(3) == '4.0'
|
224
|
+
it 'evaluates conditions for multiple belongs_to associations to the
|
225
|
+
same table contextually' do
|
226
|
+
s = Search.new(Recommendation,
|
227
|
+
person_name_eq: 'Ernie',
|
228
|
+
target_person_parent_name_eq: 'Test'
|
229
|
+
).result
|
230
|
+
expect(s).to be_an ActiveRecord::Relation
|
231
|
+
real_query = remove_quotes_and_backticks(s.to_sql)
|
232
|
+
expected_query = <<-SQL
|
233
|
+
SELECT recommendations.* FROM recommendations
|
234
|
+
LEFT OUTER JOIN people ON people.id = recommendations.person_id
|
235
|
+
LEFT OUTER JOIN people target_people_recommendations
|
236
|
+
ON target_people_recommendations.id = recommendations.target_person_id
|
237
|
+
LEFT OUTER JOIN people parents_people
|
238
|
+
ON parents_people.id = target_people_recommendations.parent_id
|
239
|
+
WHERE ((people.name = 'Ernie' AND parents_people.name = 'Test'))
|
240
|
+
SQL
|
241
|
+
.squish
|
242
|
+
expect(real_query).to eq expected_query
|
243
|
+
end
|
215
244
|
end
|
216
245
|
|
217
246
|
it 'evaluates compound conditions contextually' do
|
218
|
-
search = Search.new(Person, :
|
219
|
-
expect(search
|
220
|
-
|
221
|
-
expect(where.to_sql).to match /#{children_people_name_field
|
247
|
+
search = Search.new(Person, children_name_or_name_eq: 'Ernie').result
|
248
|
+
expect(search).to be_an ActiveRecord::Relation
|
249
|
+
expect(search.to_sql).to match /#{children_people_name_field
|
222
250
|
} = 'Ernie' OR #{people_name_field} = 'Ernie'/
|
223
251
|
end
|
224
252
|
|
225
253
|
it 'evaluates polymorphic belongs_to association conditions contextually' do
|
226
|
-
search = Search.new(Note, :
|
227
|
-
|
228
|
-
|
229
|
-
expect(
|
254
|
+
search = Search.new(Note, notable_of_Person_type_name_eq: 'Ernie')
|
255
|
+
.result
|
256
|
+
expect(search).to be_an ActiveRecord::Relation
|
257
|
+
expect(search.to_sql).to match /#{people_name_field} = 'Ernie'/
|
230
258
|
end
|
231
259
|
|
232
260
|
it 'evaluates nested conditions' do
|
233
|
-
search = Search.new(Person, :
|
234
|
-
:
|
235
|
-
{ :
|
236
|
-
:name_eq => 'Ernie',
|
237
|
-
:children_children_name_eq => 'Ernie'
|
238
|
-
}
|
261
|
+
search = Search.new(Person, children_name_eq: 'Ernie',
|
262
|
+
g: [
|
263
|
+
{ m: 'or', name_eq: 'Ernie', children_children_name_eq: 'Ernie' }
|
239
264
|
]
|
240
|
-
)
|
241
|
-
expect(search
|
242
|
-
|
243
|
-
expect(
|
244
|
-
expect(
|
245
|
-
|
246
|
-
|
265
|
+
).result
|
266
|
+
expect(search).to be_an ActiveRecord::Relation
|
267
|
+
first, last = search.to_sql.split(/ AND /)
|
268
|
+
expect(first).to match /#{children_people_name_field} = 'Ernie'/
|
269
|
+
expect(last).to match /#{
|
270
|
+
people_name_field} = 'Ernie' OR #{
|
271
|
+
quote_table_name("children_people_2")}.#{
|
272
|
+
quote_column_name("name")} = 'Ernie'/
|
247
273
|
end
|
248
274
|
|
249
275
|
it 'evaluates arrays of groupings' do
|
250
276
|
search = Search.new(Person,
|
251
|
-
:
|
252
|
-
{ :
|
253
|
-
{ :
|
277
|
+
g: [
|
278
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' },
|
279
|
+
{ m: 'or', name_eq: 'Bert', children_name_eq: 'Bert' }
|
254
280
|
]
|
255
|
-
)
|
256
|
-
expect(search
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
expect(
|
261
|
-
|
262
|
-
expect(second).to match /#{people_name_field} = 'Bert'/
|
263
|
-
expect(second).to match /#{children_people_name_field} = 'Bert'/
|
281
|
+
).result
|
282
|
+
expect(search).to be_an ActiveRecord::Relation
|
283
|
+
first, last = search.to_sql.split(/ AND /)
|
284
|
+
expect(first).to match /#{people_name_field} = 'Ernie' OR #{
|
285
|
+
children_people_name_field} = 'Ernie'/
|
286
|
+
expect(last).to match /#{people_name_field} = 'Bert' OR #{
|
287
|
+
children_people_name_field} = 'Bert'/
|
264
288
|
end
|
265
289
|
|
266
|
-
it 'returns distinct records when passed :
|
267
|
-
search = Search.new(
|
268
|
-
|
269
|
-
{ :
|
270
|
-
:comments_body_cont => 'e',
|
271
|
-
:articles_comments_body_cont => 'e'
|
272
|
-
}
|
290
|
+
it 'returns distinct records when passed distinct: true' do
|
291
|
+
search = Search.new(Person,
|
292
|
+
g: [
|
293
|
+
{ m: 'or', comments_body_cont: 'e', articles_comments_body_cont: 'e' }
|
273
294
|
]
|
274
295
|
)
|
275
296
|
if ActiveRecord::VERSION::MAJOR == 3
|
@@ -279,11 +300,17 @@ module Ransack
|
|
279
300
|
end
|
280
301
|
expect(search.result.send(all_or_load).size)
|
281
302
|
.to eq(9000)
|
282
|
-
expect(search.result(:
|
303
|
+
expect(search.result(distinct: true).size)
|
283
304
|
.to eq(10)
|
284
305
|
expect(search.result.send(all_or_load).send(uniq_or_distinct))
|
285
|
-
.to eq search.result(:
|
306
|
+
.to eq search.result(distinct: true).send(all_or_load)
|
286
307
|
end
|
308
|
+
|
309
|
+
private
|
310
|
+
|
311
|
+
def remove_quotes_and_backticks(str)
|
312
|
+
str.gsub(/["`]/, '')
|
313
|
+
end
|
287
314
|
end
|
288
315
|
|
289
316
|
describe '#sorts=' do
|
@@ -319,7 +346,7 @@ module Ransack
|
|
319
346
|
end
|
320
347
|
|
321
348
|
it 'creates sorts based on multiple attributes/directions in array format' do
|
322
|
-
@s.sorts = ['id desc', { :
|
349
|
+
@s.sorts = ['id desc', { name: 'name', dir: 'asc' }]
|
323
350
|
expect(@s.sorts.size).to eq(2)
|
324
351
|
sort1, sort2 = @s.sorts
|
325
352
|
expect(sort1).to be_a Nodes::Sort
|
@@ -331,7 +358,7 @@ module Ransack
|
|
331
358
|
end
|
332
359
|
|
333
360
|
it 'creates sorts based on multiple attributes and uppercase directions in array format' do
|
334
|
-
@s.sorts = ['id DESC', { :
|
361
|
+
@s.sorts = ['id DESC', { name: 'name', dir: 'ASC' }]
|
335
362
|
expect(@s.sorts.size).to eq(2)
|
336
363
|
sort1, sort2 = @s.sorts
|
337
364
|
expect(sort1).to be_a Nodes::Sort
|
@@ -342,7 +369,8 @@ module Ransack
|
|
342
369
|
expect(sort2.dir).to eq 'asc'
|
343
370
|
end
|
344
371
|
|
345
|
-
it 'creates sorts based on multiple attributes and different directions
|
372
|
+
it 'creates sorts based on multiple attributes and different directions
|
373
|
+
in array format' do
|
346
374
|
@s.sorts = ['id DESC', { name: 'name', dir: nil }]
|
347
375
|
expect(@s.sorts.size).to eq(2)
|
348
376
|
sort1, sort2 = @s.sorts
|
@@ -356,8 +384,8 @@ module Ransack
|
|
356
384
|
|
357
385
|
it 'creates sorts based on multiple attributes/directions in hash format' do
|
358
386
|
@s.sorts = {
|
359
|
-
'0' => { :
|
360
|
-
'1' => { :
|
387
|
+
'0' => { name: 'id', dir: 'desc' },
|
388
|
+
'1' => { name: 'name', dir: 'asc' }
|
361
389
|
}
|
362
390
|
expect(@s.sorts.size).to eq(2)
|
363
391
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
@@ -367,10 +395,11 @@ module Ransack
|
|
367
395
|
expect(name_sort.dir).to eq 'asc'
|
368
396
|
end
|
369
397
|
|
370
|
-
it 'creates sorts based on multiple attributes and uppercase directions
|
398
|
+
it 'creates sorts based on multiple attributes and uppercase directions
|
399
|
+
in hash format' do
|
371
400
|
@s.sorts = {
|
372
|
-
'0' => { :
|
373
|
-
'1' => { :
|
401
|
+
'0' => { name: 'id', dir: 'DESC' },
|
402
|
+
'1' => { name: 'name', dir: 'ASC' }
|
374
403
|
}
|
375
404
|
expect(@s.sorts.size).to eq(2)
|
376
405
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
@@ -380,10 +409,11 @@ module Ransack
|
|
380
409
|
expect(name_sort.dir).to eq 'asc'
|
381
410
|
end
|
382
411
|
|
383
|
-
it 'creates sorts based on multiple attributes and different directions
|
412
|
+
it 'creates sorts based on multiple attributes and different directions
|
413
|
+
in hash format' do
|
384
414
|
@s.sorts = {
|
385
|
-
'0' => { :
|
386
|
-
'1' => { :
|
415
|
+
'0' => { name: 'id', dir: 'DESC' },
|
416
|
+
'1' => { name: 'name', dir: nil }
|
387
417
|
}
|
388
418
|
expect(@s.sorts.size).to eq(2)
|
389
419
|
expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
|
@@ -415,7 +445,7 @@ module Ransack
|
|
415
445
|
|
416
446
|
it 'allows chaining to access nested conditions' do
|
417
447
|
@s.groupings = [
|
418
|
-
{ :
|
448
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' }
|
419
449
|
]
|
420
450
|
expect(@s.groupings.first.children_name_eq).to eq 'Ernie'
|
421
451
|
end
|