ransack 1.7.0 → 2.4.1
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 +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/test.yml +120 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +463 -27
- data/CONTRIBUTING.md +52 -22
- data/Gemfile +24 -24
- data/README.md +453 -126
- data/Rakefile +6 -25
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/join.rb +70 -0
- data/lib/polyamorous/polyamorous.rb +24 -0
- data/lib/polyamorous/swapping_reflection_class.rb +11 -0
- data/lib/polyamorous/tree_node.rb +7 -0
- data/lib/ransack/adapters/active_record/base.rb +27 -2
- data/lib/ransack/adapters/active_record/context.rb +213 -139
- data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
- data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
- data/lib/ransack/adapters/active_record.rb +11 -10
- data/lib/ransack/adapters.rb +45 -23
- data/lib/ransack/configuration.rb +107 -4
- data/lib/ransack/constants.rb +13 -26
- data/lib/ransack/context.rb +45 -33
- data/lib/ransack/helpers/form_builder.rb +21 -12
- data/lib/ransack/helpers/form_helper.rb +75 -70
- data/lib/ransack/locale/ar.yml +70 -0
- data/lib/ransack/locale/az.yml +70 -0
- data/lib/ransack/locale/bg.yml +70 -0
- data/lib/ransack/locale/ca.yml +70 -0
- data/lib/ransack/locale/da.yml +70 -0
- data/lib/ransack/locale/el.yml +70 -0
- data/lib/ransack/locale/es.yml +22 -22
- data/lib/ransack/locale/fa.yml +70 -0
- data/lib/ransack/locale/fi.yml +71 -0
- data/lib/ransack/locale/id.yml +70 -0
- data/lib/ransack/locale/it.yml +70 -0
- data/lib/ransack/locale/ja.yml +70 -0
- data/lib/ransack/locale/nl.yml +4 -4
- data/lib/ransack/locale/pt-BR.yml +70 -0
- data/lib/ransack/locale/ru.yml +70 -0
- data/lib/ransack/locale/sk.yml +70 -0
- data/lib/ransack/locale/tr.yml +70 -0
- data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
- data/lib/ransack/locale/zh-TW.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +5 -2
- data/lib/ransack/nodes/bindable.rb +18 -6
- data/lib/ransack/nodes/condition.rb +85 -28
- data/lib/ransack/nodes/grouping.rb +17 -11
- data/lib/ransack/nodes/sort.rb +9 -5
- data/lib/ransack/nodes/value.rb +74 -68
- data/lib/ransack/nodes.rb +1 -1
- data/lib/ransack/predicate.rb +17 -20
- data/lib/ransack/search.rb +17 -8
- data/lib/ransack/translate.rb +115 -115
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +1 -12
- data/lib/ransack.rb +9 -9
- data/logo/ransack-h.png +0 -0
- data/logo/ransack-h.svg +34 -0
- data/logo/ransack-v.png +0 -0
- data/logo/ransack-v.svg +34 -0
- data/logo/ransack.png +0 -0
- data/logo/ransack.svg +21 -0
- data/ransack.gemspec +7 -24
- data/spec/console.rb +4 -0
- data/spec/helpers/polyamorous_helper.rb +19 -0
- data/spec/polyamorous/join_association_spec.rb +35 -0
- data/spec/polyamorous/join_dependency_spec.rb +97 -0
- data/spec/polyamorous/join_spec.rb +19 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
- data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
- data/spec/ransack/configuration_spec.rb +97 -14
- data/spec/ransack/helpers/form_builder_spec.rb +2 -11
- data/spec/ransack/helpers/form_helper_spec.rb +481 -113
- data/spec/ransack/nodes/condition_spec.rb +24 -0
- data/spec/ransack/nodes/grouping_spec.rb +56 -0
- data/spec/ransack/predicate_spec.rb +79 -5
- data/spec/ransack/search_spec.rb +207 -81
- data/spec/spec_helper.rb +8 -0
- data/spec/support/schema.rb +100 -42
- metadata +57 -184
- data/.travis.yml +0 -69
- data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
- data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
- data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
- data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
- data/lib/ransack/adapters/active_record/compat.rb +0 -14
- data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
- data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
- data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
- data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
- data/lib/ransack/adapters/mongoid/base.rb +0 -130
- data/lib/ransack/adapters/mongoid/context.rb +0 -208
- data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
- data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
- data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
- data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
- data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
- data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
- data/lib/ransack/adapters/mongoid/table.rb +0 -35
- data/lib/ransack/adapters/mongoid.rb +0 -13
- data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
- data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
- data/spec/mongoid/configuration_spec.rb +0 -102
- data/spec/mongoid/dependencies_spec.rb +0 -8
- data/spec/mongoid/helpers/ransack_helper.rb +0 -11
- data/spec/mongoid/nodes/condition_spec.rb +0 -34
- data/spec/mongoid/nodes/grouping_spec.rb +0 -13
- data/spec/mongoid/predicate_spec.rb +0 -155
- data/spec/mongoid/search_spec.rb +0 -446
- data/spec/mongoid/support/mongoid.yml +0 -6
- data/spec/mongoid/support/schema.rb +0 -128
- data/spec/mongoid/translate_spec.rb +0 -14
- data/spec/mongoid_spec_helper.rb +0 -59
- data/spec/ransack/dependencies_spec.rb +0 -12
|
@@ -4,6 +4,21 @@ module Ransack
|
|
|
4
4
|
module Nodes
|
|
5
5
|
describe Condition do
|
|
6
6
|
|
|
7
|
+
context 'with an alias' do
|
|
8
|
+
subject {
|
|
9
|
+
Condition.extract(
|
|
10
|
+
Context.for(Person), 'term_start', Person.first(2).map(&:name)
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
specify { expect(subject.combinator).to eq 'or' }
|
|
15
|
+
specify { expect(subject.predicate.name).to eq 'start' }
|
|
16
|
+
|
|
17
|
+
it 'converts the alias to the correct attributes' do
|
|
18
|
+
expect(subject.attributes.map(&:name)).to eq(['name', 'email'])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
7
22
|
context 'with multiple values and an _any predicate' do
|
|
8
23
|
subject {
|
|
9
24
|
Condition.extract(
|
|
@@ -14,6 +29,15 @@ module Ransack
|
|
|
14
29
|
specify { expect(subject.values.size).to eq(2) }
|
|
15
30
|
end
|
|
16
31
|
|
|
32
|
+
describe '#negative?' do
|
|
33
|
+
let(:context) { Context.for(Person) }
|
|
34
|
+
let(:eq) { Condition.extract(context, 'name_eq', 'A') }
|
|
35
|
+
let(:not_eq) { Condition.extract(context, 'name_not_eq', 'A') }
|
|
36
|
+
|
|
37
|
+
specify { expect(not_eq.negative?).to be true }
|
|
38
|
+
specify { expect(eq.negative?).to be false }
|
|
39
|
+
end
|
|
40
|
+
|
|
17
41
|
context 'with an invalid predicate' do
|
|
18
42
|
subject {
|
|
19
43
|
Condition.extract(
|
|
@@ -50,6 +50,62 @@ module Ransack
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
describe '#conditions=' do
|
|
54
|
+
context 'when conditions are identical' do
|
|
55
|
+
let(:conditions) do
|
|
56
|
+
{
|
|
57
|
+
'0' => {
|
|
58
|
+
'a' => { '0'=> { 'name' => 'name', 'ransacker_args' => '' } },
|
|
59
|
+
'p' => 'cont',
|
|
60
|
+
'v' => { '0' => { 'value' => 'John' } }
|
|
61
|
+
},
|
|
62
|
+
'1' => {
|
|
63
|
+
'a' => { '0' => { 'name' => 'name', 'ransacker_args' => '' } },
|
|
64
|
+
'p' => 'cont',
|
|
65
|
+
'v' => { '0' => { 'value' => 'John' } }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
before { subject.conditions = conditions }
|
|
70
|
+
|
|
71
|
+
it 'expect duplicates to be removed' do
|
|
72
|
+
expect(subject.conditions.count).to eq 1
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'when conditions differ only by ransacker_args' do
|
|
77
|
+
let(:conditions) do
|
|
78
|
+
{
|
|
79
|
+
'0' => {
|
|
80
|
+
'a' => {
|
|
81
|
+
'0' => {
|
|
82
|
+
'name' => 'with_arguments',
|
|
83
|
+
'ransacker_args' => [1,2]
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
'p' => 'eq',
|
|
87
|
+
'v' => { '0' => { 'value' => '10' } }
|
|
88
|
+
},
|
|
89
|
+
'1' => {
|
|
90
|
+
'a' => {
|
|
91
|
+
'0' => {
|
|
92
|
+
'name' => 'with_arguments',
|
|
93
|
+
'ransacker_args' => [3,4]
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
'p' => 'eq',
|
|
97
|
+
'v' => { '0' => { 'value' => '10' } }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
before { subject.conditions = conditions }
|
|
102
|
+
|
|
103
|
+
it 'expect them to be parsed as different and not as duplicates' do
|
|
104
|
+
expect(subject.conditions.count).to eq 2
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
53
109
|
end
|
|
54
110
|
end
|
|
55
111
|
end
|
|
@@ -16,7 +16,7 @@ module Ransack
|
|
|
16
16
|
expect { subject.result }.to_not raise_error
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
it "escapes '%', '.' and '\\\\' in value" do
|
|
19
|
+
it "escapes '%', '.', '_' and '\\\\' in value" do
|
|
20
20
|
subject.send(:"#{method}=", '%._\\')
|
|
21
21
|
expect(subject.result.to_sql).to match(regexp)
|
|
22
22
|
end
|
|
@@ -124,9 +124,9 @@ module Ransack
|
|
|
124
124
|
describe 'cont' do
|
|
125
125
|
it_has_behavior 'wildcard escaping', :name_cont,
|
|
126
126
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
127
|
-
/"people"."name" ILIKE '
|
|
127
|
+
/"people"."name" ILIKE '%\\%\\.\\_\\\\%'/
|
|
128
128
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
|
129
|
-
/`people`.`name` LIKE '
|
|
129
|
+
/`people`.`name` LIKE '%\\\\%.\\\\_\\\\\\\\%'/
|
|
130
130
|
else
|
|
131
131
|
/"people"."name" LIKE '%%._\\%'/
|
|
132
132
|
end) do
|
|
@@ -143,9 +143,9 @@ module Ransack
|
|
|
143
143
|
describe 'not_cont' do
|
|
144
144
|
it_has_behavior 'wildcard escaping', :name_not_cont,
|
|
145
145
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
146
|
-
/"people"."name" NOT ILIKE '
|
|
146
|
+
/"people"."name" NOT ILIKE '%\\%\\.\\_\\\\%'/
|
|
147
147
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
|
148
|
-
/`people`.`name` NOT LIKE '
|
|
148
|
+
/`people`.`name` NOT LIKE '%\\\\%.\\\\_\\\\\\\\%'/
|
|
149
149
|
else
|
|
150
150
|
/"people"."name" NOT LIKE '%%._\\%'/
|
|
151
151
|
end) do
|
|
@@ -159,6 +159,44 @@ module Ransack
|
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
|
|
162
|
+
describe 'i_cont' do
|
|
163
|
+
it_has_behavior 'wildcard escaping', :name_i_cont,
|
|
164
|
+
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
165
|
+
/"people"."name" ILIKE '%\\%\\.\\_\\\\%'/
|
|
166
|
+
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
|
167
|
+
/LOWER\(`people`.`name`\) LIKE '%\\\\%.\\\\_\\\\\\\\%'/
|
|
168
|
+
else
|
|
169
|
+
/LOWER\("people"."name"\) LIKE '%%._\\%'/
|
|
170
|
+
end) do
|
|
171
|
+
subject { @s }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'generates a LIKE query with LOWER(column) and value surrounded by %' do
|
|
175
|
+
@s.name_i_cont = 'Ric'
|
|
176
|
+
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
177
|
+
expect(@s.result.to_sql).to match /[LOWER\(]?#{field}\)? I?LIKE '%ric%'/
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe 'not_i_cont' do
|
|
182
|
+
it_has_behavior 'wildcard escaping', :name_not_i_cont,
|
|
183
|
+
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
184
|
+
/"people"."name" NOT ILIKE '%\\%\\.\\_\\\\%'/
|
|
185
|
+
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
|
186
|
+
/LOWER\(`people`.`name`\) NOT LIKE '%\\\\%.\\\\_\\\\\\\\%'/
|
|
187
|
+
else
|
|
188
|
+
/LOWER\("people"."name"\) NOT LIKE '%%._\\%'/
|
|
189
|
+
end) do
|
|
190
|
+
subject { @s }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'generates a NOT LIKE query with LOWER(column) and value surrounded by %' do
|
|
194
|
+
@s.name_not_i_cont = 'Ric'
|
|
195
|
+
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
196
|
+
expect(@s.result.to_sql).to match /[LOWER\(]?#{field}\)? NOT I?LIKE '%ric%'/
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
162
200
|
describe 'start' do
|
|
163
201
|
it 'generates a LIKE query with value followed by %' do
|
|
164
202
|
@s.name_start = 'Er'
|
|
@@ -329,6 +367,28 @@ module Ransack
|
|
|
329
367
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
330
368
|
expect(@s.result.to_sql).to match /#{field} IS NULL/
|
|
331
369
|
end
|
|
370
|
+
|
|
371
|
+
describe 'with association qeury' do
|
|
372
|
+
it 'generates a value IS NOT NULL query' do
|
|
373
|
+
@s.comments_id_not_null = true
|
|
374
|
+
sql = @s.result.to_sql
|
|
375
|
+
parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
|
|
376
|
+
expect(sql).to match /#{parent_field} IN/
|
|
377
|
+
field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
|
|
378
|
+
expect(sql).to match /#{field} IS NOT NULL/
|
|
379
|
+
expect(sql).not_to match /AND NOT/
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it 'generates a value IS NULL query when assigned false' do
|
|
383
|
+
@s.comments_id_not_null = false
|
|
384
|
+
sql = @s.result.to_sql
|
|
385
|
+
parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
|
|
386
|
+
expect(sql).to match /#{parent_field} NOT IN/
|
|
387
|
+
field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
|
|
388
|
+
expect(sql).to match /#{field} IS NULL/
|
|
389
|
+
expect(sql).to match /AND NOT/
|
|
390
|
+
end
|
|
391
|
+
end
|
|
332
392
|
end
|
|
333
393
|
|
|
334
394
|
describe 'present' do
|
|
@@ -359,6 +419,20 @@ module Ransack
|
|
|
359
419
|
end
|
|
360
420
|
end
|
|
361
421
|
|
|
422
|
+
context "defining custom predicates" do
|
|
423
|
+
describe "with 'not_in' arel predicate" do
|
|
424
|
+
before do
|
|
425
|
+
Ransack.configure {|c| c.add_predicate "not_in_csv", arel_predicate: "not_in", formatter: proc { |v| v.split(",") } }
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
it 'generates a value IS NOT NULL query' do
|
|
429
|
+
@s.name_not_in_csv = ["a", "b"]
|
|
430
|
+
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
431
|
+
expect(@s.result.to_sql).to match /#{field} NOT IN \('a', 'b'\)/
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
362
436
|
private
|
|
363
437
|
|
|
364
438
|
def test_boolean_equality_for(boolean_value)
|