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.
Files changed (127) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/SECURITY.md +12 -0
  4. data/.github/workflows/test.yml +120 -0
  5. data/.gitignore +3 -0
  6. data/CHANGELOG.md +463 -27
  7. data/CONTRIBUTING.md +52 -22
  8. data/Gemfile +24 -24
  9. data/README.md +453 -126
  10. data/Rakefile +6 -25
  11. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
  12. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
  13. data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
  14. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
  15. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
  16. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
  17. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
  18. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
  19. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
  20. data/lib/polyamorous/join.rb +70 -0
  21. data/lib/polyamorous/polyamorous.rb +24 -0
  22. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  23. data/lib/polyamorous/tree_node.rb +7 -0
  24. data/lib/ransack/adapters/active_record/base.rb +27 -2
  25. data/lib/ransack/adapters/active_record/context.rb +213 -139
  26. data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
  27. data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
  28. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
  29. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
  30. data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
  31. data/lib/ransack/adapters/active_record.rb +11 -10
  32. data/lib/ransack/adapters.rb +45 -23
  33. data/lib/ransack/configuration.rb +107 -4
  34. data/lib/ransack/constants.rb +13 -26
  35. data/lib/ransack/context.rb +45 -33
  36. data/lib/ransack/helpers/form_builder.rb +21 -12
  37. data/lib/ransack/helpers/form_helper.rb +75 -70
  38. data/lib/ransack/locale/ar.yml +70 -0
  39. data/lib/ransack/locale/az.yml +70 -0
  40. data/lib/ransack/locale/bg.yml +70 -0
  41. data/lib/ransack/locale/ca.yml +70 -0
  42. data/lib/ransack/locale/da.yml +70 -0
  43. data/lib/ransack/locale/el.yml +70 -0
  44. data/lib/ransack/locale/es.yml +22 -22
  45. data/lib/ransack/locale/fa.yml +70 -0
  46. data/lib/ransack/locale/fi.yml +71 -0
  47. data/lib/ransack/locale/id.yml +70 -0
  48. data/lib/ransack/locale/it.yml +70 -0
  49. data/lib/ransack/locale/ja.yml +70 -0
  50. data/lib/ransack/locale/nl.yml +4 -4
  51. data/lib/ransack/locale/pt-BR.yml +70 -0
  52. data/lib/ransack/locale/ru.yml +70 -0
  53. data/lib/ransack/locale/sk.yml +70 -0
  54. data/lib/ransack/locale/tr.yml +70 -0
  55. data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
  56. data/lib/ransack/locale/zh-TW.yml +70 -0
  57. data/lib/ransack/nodes/attribute.rb +5 -2
  58. data/lib/ransack/nodes/bindable.rb +18 -6
  59. data/lib/ransack/nodes/condition.rb +85 -28
  60. data/lib/ransack/nodes/grouping.rb +17 -11
  61. data/lib/ransack/nodes/sort.rb +9 -5
  62. data/lib/ransack/nodes/value.rb +74 -68
  63. data/lib/ransack/nodes.rb +1 -1
  64. data/lib/ransack/predicate.rb +17 -20
  65. data/lib/ransack/search.rb +17 -8
  66. data/lib/ransack/translate.rb +115 -115
  67. data/lib/ransack/version.rb +1 -1
  68. data/lib/ransack/visitor.rb +1 -12
  69. data/lib/ransack.rb +9 -9
  70. data/logo/ransack-h.png +0 -0
  71. data/logo/ransack-h.svg +34 -0
  72. data/logo/ransack-v.png +0 -0
  73. data/logo/ransack-v.svg +34 -0
  74. data/logo/ransack.png +0 -0
  75. data/logo/ransack.svg +21 -0
  76. data/ransack.gemspec +7 -24
  77. data/spec/console.rb +4 -0
  78. data/spec/helpers/polyamorous_helper.rb +19 -0
  79. data/spec/polyamorous/join_association_spec.rb +35 -0
  80. data/spec/polyamorous/join_dependency_spec.rb +97 -0
  81. data/spec/polyamorous/join_spec.rb +19 -0
  82. data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
  83. data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
  84. data/spec/ransack/configuration_spec.rb +97 -14
  85. data/spec/ransack/helpers/form_builder_spec.rb +2 -11
  86. data/spec/ransack/helpers/form_helper_spec.rb +481 -113
  87. data/spec/ransack/nodes/condition_spec.rb +24 -0
  88. data/spec/ransack/nodes/grouping_spec.rb +56 -0
  89. data/spec/ransack/predicate_spec.rb +79 -5
  90. data/spec/ransack/search_spec.rb +207 -81
  91. data/spec/spec_helper.rb +8 -0
  92. data/spec/support/schema.rb +100 -42
  93. metadata +57 -184
  94. data/.travis.yml +0 -69
  95. data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
  96. data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
  97. data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
  98. data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
  99. data/lib/ransack/adapters/active_record/compat.rb +0 -14
  100. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  101. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
  102. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
  103. data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
  104. data/lib/ransack/adapters/mongoid/base.rb +0 -130
  105. data/lib/ransack/adapters/mongoid/context.rb +0 -208
  106. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
  107. data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
  108. data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
  109. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
  110. data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
  111. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
  112. data/lib/ransack/adapters/mongoid/table.rb +0 -35
  113. data/lib/ransack/adapters/mongoid.rb +0 -13
  114. data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
  115. data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
  116. data/spec/mongoid/configuration_spec.rb +0 -102
  117. data/spec/mongoid/dependencies_spec.rb +0 -8
  118. data/spec/mongoid/helpers/ransack_helper.rb +0 -11
  119. data/spec/mongoid/nodes/condition_spec.rb +0 -34
  120. data/spec/mongoid/nodes/grouping_spec.rb +0 -13
  121. data/spec/mongoid/predicate_spec.rb +0 -155
  122. data/spec/mongoid/search_spec.rb +0 -446
  123. data/spec/mongoid/support/mongoid.yml +0 -6
  124. data/spec/mongoid/support/schema.rb +0 -128
  125. data/spec/mongoid/translate_spec.rb +0 -14
  126. data/spec/mongoid_spec_helper.rb +0 -59
  127. data/spec/ransack/dependencies_spec.rb +0 -12
@@ -1,155 +0,0 @@
1
- require 'mongoid_spec_helper'
2
-
3
- module Ransack
4
- describe Predicate do
5
-
6
- before do
7
- @s = Search.new(Person)
8
- end
9
-
10
- shared_examples 'wildcard escaping' do |method, value|
11
- it 'automatically converts integers to strings' do
12
- subject.parent_id_cont = 1
13
- expect { subject.result }.to_not raise_error
14
- end
15
-
16
- it "escapes '%', '.' and '\\\\' in value" do
17
- subject.send(:"#{method}=", '%._\\')
18
- expect(subject.result.selector).to eq(value)
19
- end
20
- end
21
-
22
- describe 'eq' do
23
- it 'generates an equality condition for boolean true' do
24
- @s.awesome_eq = true
25
- expect(@s.result.selector).to eq({ "awesome" => true })
26
- end
27
-
28
- it 'generates an equality condition for boolean false' do
29
- @s.awesome_eq = false
30
- expect(@s.result.selector).to eq({ "awesome" => false })
31
- end
32
-
33
- it 'does not generate a condition for nil' do
34
- @s.awesome_eq = nil
35
- expect(@s.result.selector).to eq({ })
36
- end
37
- end
38
-
39
- describe 'cont' do
40
- it_has_behavior 'wildcard escaping', :name_cont, { 'name' => /%\._\\/i } do
41
- subject { @s }
42
- end
43
-
44
- it 'generates a regex query' do
45
- @s.name_cont = 'ric'
46
- expect(@s.result.selector).to eq({ 'name' => /ric/i })
47
- end
48
- end
49
-
50
- describe 'not_cont' do
51
- it_has_behavior 'wildcard escaping', :name_not_cont, { "$not" => { 'name' => /%\._\\/i } } do
52
- subject { @s }
53
- end
54
-
55
- it 'generates a regex query' do
56
- @s.name_not_cont = 'ric'
57
- expect(@s.result.selector).to eq({ "$not" => { 'name' => /ric/i } })
58
- end
59
- end
60
-
61
- describe 'null' do
62
- it 'generates a value IS NULL query' do
63
- @s.name_null = true
64
- expect(@s.result.selector).to eq({ 'name' => nil })
65
- end
66
-
67
- it 'generates a value IS NOT NULL query when assigned false' do
68
- @s.name_null = false
69
- expect(@s.result.selector).to eq( { 'name' => { '$ne' => nil } })
70
- end
71
- end
72
-
73
- describe 'not_null' do
74
- it 'generates a value IS NOT NULL query' do
75
- @s.name_not_null = true
76
- expect(@s.result.selector).to eq({ 'name' => { '$ne' => nil } })
77
- end
78
-
79
- it 'generates a value IS NULL query when assigned false' do
80
- @s.name_not_null = false
81
- expect(@s.result.selector).to eq({ 'name' => nil })
82
- end
83
- end
84
-
85
- describe 'present' do
86
- it %q[generates a value IS NOT NULL AND value != '' query] do
87
- @s.name_present = true
88
- expect(@s.result.selector).to eq({ '$and' => [ { 'name' => { '$ne' => nil } }, { 'name' => { '$ne' => '' } } ] })
89
- end
90
-
91
- it %q[generates a value IS NULL OR value = '' query when assigned false] do
92
- @s.name_present = false
93
- expect(@s.result.selector).to eq({ '$or' => [ { 'name' => nil }, { 'name' => '' } ] })
94
- end
95
- end
96
-
97
- describe 'blank' do
98
- it %q[generates a value IS NULL OR value = '' query] do
99
- @s.name_blank = true
100
- expect(@s.result.selector).to eq({ '$or' => [ { 'name' => nil}, { 'name' => '' } ] })
101
- end
102
-
103
- it %q[generates a value IS NOT NULL AND value != '' query when assigned false] do
104
- @s.name_blank = false
105
- expect(@s.result.selector).to eq({ '$and' => [ { 'name' => { '$ne' => nil}}, { 'name' => { '$ne' => '' }} ] })
106
- end
107
- end
108
-
109
- describe 'gt' do
110
- it 'generates an greater than for time' do
111
- time = Time.now
112
- @s.created_at_gt = time
113
- expect(@s.result.selector).to eq({ "created_at" => { '$gt' => time } })
114
- end
115
- end
116
-
117
- describe 'lt' do
118
- it 'generates an greater than for time' do
119
- time = Time.now
120
- @s.created_at_lt = time
121
- expect(@s.result.selector).to eq({ "created_at" => { '$lt' => time } })
122
- end
123
- end
124
-
125
- describe 'gteq' do
126
- it 'generates an greater than for time' do
127
- time = Time.now
128
- @s.created_at_gteq = time
129
- expect(@s.result.selector).to eq({ "created_at" => { '$gte' => time } })
130
- end
131
- end
132
-
133
- describe 'lteq' do
134
- it 'generates an greater than for time' do
135
- time = Time.now
136
- @s.created_at_lteq = time
137
- expect(@s.result.selector).to eq({ "created_at" => { '$lte' => time } })
138
- end
139
- end
140
-
141
- describe 'starts_with' do
142
- it 'generates an starts_with' do
143
- @s.name_start = 'ric'
144
- expect(@s.result.selector).to eq({ "name" => /\Aric/i })
145
- end
146
- end
147
-
148
- describe 'ends_with' do
149
- it 'generates an ends_with' do
150
- @s.name_end = 'ric'
151
- expect(@s.result.selector).to eq({ "name" => /ric\Z/i })
152
- end
153
- end
154
- end
155
- end
@@ -1,446 +0,0 @@
1
- require 'mongoid_spec_helper'
2
-
3
- module Ransack
4
- describe Search do
5
- describe '#initialize' do
6
- it "removes empty conditions before building" do
7
- expect_any_instance_of(Search).to receive(:build).with({})
8
- Search.new(Person, :name_eq => '')
9
- end
10
-
11
- it "keeps conditions with a false value before building" do
12
- expect_any_instance_of(Search).to receive(:build).with({"name_eq" => false})
13
- Search.new(Person, :name_eq => false)
14
- end
15
-
16
- it "keeps conditions with a value before building" do
17
- expect_any_instance_of(Search).to receive(:build).with({"name_eq" => 'foobar'})
18
- Search.new(Person, :name_eq => 'foobar')
19
- end
20
-
21
- it "removes empty suffixed conditions before building" do
22
- expect_any_instance_of(Search).to receive(:build).with({})
23
- Search.new(Person, :name_eq_any => [''])
24
- end
25
-
26
- it "keeps suffixed conditions with a false value before building" do
27
- expect_any_instance_of(Search).to receive(:build).with({"name_eq_any" => [false]})
28
- Search.new(Person, :name_eq_any => [false])
29
- end
30
-
31
- it "keeps suffixed conditions with a value before building" do
32
- expect_any_instance_of(Search).to receive(:build).with({"name_eq_any" => ['foobar']})
33
- Search.new(Person, :name_eq_any => ['foobar'])
34
- end
35
-
36
- it 'does not raise exception for string :params argument' do
37
- expect { Search.new(Person, '') }.not_to raise_error
38
- end
39
- end
40
-
41
- describe '#build' do
42
- it 'creates conditions for top-level attributes' do
43
- search = Search.new(Person, :name_eq => 'Ernie')
44
- condition = search.base[:name_eq]
45
- expect(condition).to be_a Nodes::Condition
46
- expect(condition.predicate.name).to eq 'eq'
47
- expect(condition.attributes.first.name).to eq 'name'
48
- expect(condition.value).to eq 'Ernie'
49
- end
50
-
51
- context 'joins' do
52
- before { pending 'not implemented for mongoid' }
53
-
54
- it 'creates conditions for association attributes' do
55
- search = Search.new(Person, :children_name_eq => 'Ernie')
56
- condition = search.base[:children_name_eq]
57
- expect(condition).to be_a Nodes::Condition
58
- expect(condition.predicate.name).to eq 'eq'
59
- expect(condition.attributes.first.name).to eq 'children_name'
60
- expect(condition.value).to eq 'Ernie'
61
- end
62
-
63
- it 'creates conditions for polymorphic belongs_to association attributes' do
64
- search = Search.new(Note, :notable_of_Person_type_name_eq => 'Ernie')
65
- condition = search.base[:notable_of_Person_type_name_eq]
66
- expect(condition).to be_a Nodes::Condition
67
- expect(condition.predicate.name).to eq 'eq'
68
- expect(condition.attributes.first.name).to eq 'notable_of_Person_type_name'
69
- expect(condition.value).to eq 'Ernie'
70
- end
71
-
72
- it 'creates conditions for multiple polymorphic belongs_to association attributes' do
73
- search = Search.new(Note,
74
- :notable_of_Person_type_name_or_notable_of_Article_type_title_eq => 'Ernie')
75
- condition = search.
76
- base[:notable_of_Person_type_name_or_notable_of_Article_type_title_eq]
77
- expect(condition).to be_a Nodes::Condition
78
- expect(condition.predicate.name).to eq 'eq'
79
- expect(condition.attributes.first.name).to eq 'notable_of_Person_type_name'
80
- expect(condition.attributes.last.name).to eq 'notable_of_Article_type_title'
81
- expect(condition.value).to eq 'Ernie'
82
- end
83
- before { skip }
84
- it 'accepts arrays of groupings with joins' do
85
- search = Search.new(Person,
86
- g: [
87
- { :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' },
88
- { :m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert' },
89
- ]
90
- )
91
- ors = search.groupings
92
- expect(ors.size).to eq(2)
93
- or1, or2 = ors
94
- expect(or1).to be_a Nodes::Grouping
95
- expect(or1.combinator).to eq 'or'
96
- expect(or2).to be_a Nodes::Grouping
97
- expect(or2.combinator).to eq 'or'
98
- end
99
-
100
- it 'accepts "attributes" hashes for groupings' do
101
- search = Search.new(Person,
102
- g: {
103
- '0' => { m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' },
104
- '1' => { m: 'or', name_eq: 'Bert', children_name_eq: 'Bert' },
105
- }
106
- )
107
- ors = search.groupings
108
- expect(ors.size).to eq(2)
109
- or1, or2 = ors
110
- expect(or1).to be_a Nodes::Grouping
111
- expect(or1.combinator).to eq 'or'
112
- expect(or2).to be_a Nodes::Grouping
113
- expect(or2.combinator).to eq 'or'
114
- end
115
-
116
- it 'accepts "attributes" hashes for conditions' do
117
- search = Search.new(Person,
118
- :c => {
119
- '0' => { :a => ['name'], :p => 'eq', :v => ['Ernie'] },
120
- '1' => { :a => ['children_name', 'parent_name'],
121
- :p => 'eq', :v => ['Ernie'], :m => 'or' }
122
- }
123
- )
124
- conditions = search.base.conditions
125
- expect(conditions.size).to eq(2)
126
- expect(conditions.map { |c| c.class })
127
- .to eq [Nodes::Condition, Nodes::Condition]
128
- end
129
-
130
- before { skip }
131
- it 'does not evaluate the query on #inspect' do
132
- search = Search.new(Person, :children_id_in => [1, 2, 3])
133
- expect(search.inspect).not_to match /ActiveRecord/
134
- end
135
- end
136
-
137
- it 'discards empty conditions' do
138
- search = Search.new(Person, :children_name_eq => '')
139
- condition = search.base[:children_name_eq]
140
- expect(condition).to be_nil
141
- end
142
-
143
- it 'accepts arrays of groupings' do
144
- search = Search.new(Person,
145
- g: [
146
- { :m => 'or', :name_eq => 'Ernie', :email_eq => 'ernie@example.org' },
147
- { :m => 'or', :name_eq => 'Bert', :email_eq => 'bert@example.org' },
148
- ]
149
- )
150
- ors = search.groupings
151
- expect(ors.size).to eq(2)
152
- or1, or2 = ors
153
- expect(or1).to be_a Nodes::Grouping
154
- expect(or1.combinator).to eq 'or'
155
- expect(or2).to be_a Nodes::Grouping
156
- expect(or2.combinator).to eq 'or'
157
- end
158
-
159
- it 'creates conditions for custom predicates that take arrays' do
160
- Ransack.configure do |config|
161
- config.add_predicate 'ary_pred', :wants_array => true
162
- end
163
-
164
- search = Search.new(Person, :name_ary_pred => ['Ernie', 'Bert'])
165
- condition = search.base[:name_ary_pred]
166
- expect(condition).to be_a Nodes::Condition
167
- expect(condition.predicate.name).to eq 'ary_pred'
168
- expect(condition.attributes.first.name).to eq 'name'
169
- expect(condition.value).to eq ['Ernie', 'Bert']
170
- end
171
-
172
- context 'with an invalid condition' do
173
- subject { Search.new(Person, :unknown_attr_eq => 'Ernie') }
174
-
175
- context "when ignore_unknown_conditions is false" do
176
- before do
177
- Ransack.configure { |c| c.ignore_unknown_conditions = false }
178
- end
179
-
180
- specify { expect { subject }.to raise_error ArgumentError }
181
- end
182
-
183
- context "when ignore_unknown_conditions is true" do
184
- before do
185
- Ransack.configure { |c| c.ignore_unknown_conditions = true }
186
- end
187
-
188
- specify { expect { subject }.not_to raise_error }
189
- end
190
- end
191
- end
192
-
193
- describe '#result' do
194
- let(:people_name_field) {
195
- "#{quote_table_name("people")}.#{quote_column_name("name")}"
196
- }
197
- # let(:children_people_name_field) {
198
- # "#{quote_table_name("children_people")}.#{quote_column_name("name")}"
199
- # }
200
-
201
- it 'evaluates arrays of groupings' do
202
- search = Search.new(Person,
203
- :g => [
204
- { :m => 'or', :name_eq => 'Ernie', :email_eq => 'ernie@example.org' },
205
- { :m => 'or', :name_eq => 'Bert', :email_eq => 'bert@example.org' }
206
- ]
207
- )
208
- expect(search.result).to be_an Mongoid::Criteria
209
- selector = search.result.selector
210
- expect(selector.keys).to eq ['$and']
211
- first, second = selector.values.first
212
- expect(first).to eq({ '$or' => [ { 'name' => 'Ernie' }, { 'email' => 'ernie@example.org' } ] })
213
- expect(second).to eq({ '$or' => [ { 'name' => 'Bert' }, { 'email' => 'bert@example.org' } ] })
214
- end
215
-
216
- context 'with joins' do
217
- before { pending 'not implemented for mongoid' }
218
-
219
- it 'evaluates conditions contextually' do
220
- search = Search.new(Person, :children_name_eq => 'Ernie')
221
- expect(search.result).to be_an ActiveRecord::Relation
222
- where = search.result.where_values.first
223
- expect(where.to_sql).to match /#{children_people_name_field} = 'Ernie'/
224
- end
225
-
226
- it 'evaluates compound conditions contextually' do
227
- search = Search.new(Person, :children_name_or_name_eq => 'Ernie')
228
- expect(search.result).to be_an ActiveRecord::Relation
229
- where = search.result.where_values.first
230
- expect(where.to_sql).to match /#{children_people_name_field
231
- } = 'Ernie' OR #{people_name_field} = 'Ernie'/
232
- end
233
-
234
- it 'evaluates polymorphic belongs_to association conditions contextually' do
235
- search = Search.new(Note, :notable_of_Person_type_name_eq => 'Ernie')
236
- expect(search.result).to be_an ActiveRecord::Relation
237
- where = search.result.where_values.first
238
- expect(where.to_sql).to match /#{people_name_field} = 'Ernie'/
239
- end
240
-
241
- it 'evaluates nested conditions' do
242
- search = Search.new(Person, :children_name_eq => 'Ernie',
243
- :g => [
244
- { :m => 'or',
245
- :name_eq => 'Ernie',
246
- :children_children_name_eq => 'Ernie'
247
- }
248
- ]
249
- )
250
- expect(search.result).to be_an ActiveRecord::Relation
251
- where = search.result.where_values.first
252
- expect(where.to_sql).to match /#{children_people_name_field} = 'Ernie'/
253
- expect(where.to_sql).to match /#{people_name_field} = 'Ernie'/
254
- expect(where.to_sql).to match /#{quote_table_name("children_people_2")
255
- }.#{quote_column_name("name")} = 'Ernie'/
256
- end
257
-
258
- it 'evaluates arrays of groupings' do
259
- search = Search.new(Person,
260
- :g => [
261
- { :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' },
262
- { :m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert' }
263
- ]
264
- )
265
- expect(search.result).to be_an ActiveRecord::Relation
266
- where = search.result.where_values.first
267
- sql = where.to_sql
268
- first, second = sql.split(/ AND /)
269
- expect(first).to match /#{people_name_field} = 'Ernie'/
270
- expect(first).to match /#{children_people_name_field} = 'Ernie'/
271
- expect(second).to match /#{people_name_field} = 'Bert'/
272
- expect(second).to match /#{children_people_name_field} = 'Bert'/
273
- end
274
-
275
- it 'returns distinct records when passed :distinct => true' do
276
- search = Search.new(
277
- Person, :g => [
278
- { :m => 'or',
279
- :comments_body_cont => 'e',
280
- :articles_comments_body_cont => 'e'
281
- }
282
- ]
283
- )
284
- if ActiveRecord::VERSION::MAJOR == 3
285
- all_or_load, uniq_or_distinct = :all, :uniq
286
- else
287
- all_or_load, uniq_or_distinct = :load, :distinct
288
- end
289
- expect(search.result.send(all_or_load).size).
290
- to eq(9000)
291
- expect(search.result(:distinct => true).size).
292
- to eq(10)
293
- expect(search.result.send(all_or_load).send(uniq_or_distinct)).
294
- to eq search.result(:distinct => true).send(all_or_load)
295
- end
296
- end
297
- end
298
-
299
- describe '#sorts=' do
300
- before do
301
- @s = Search.new(Person)
302
- end
303
-
304
- it 'creates sorts based on a single attribute/direction' do
305
- @s.sorts = 'id desc'
306
- expect(@s.sorts.size).to eq(1)
307
- sort = @s.sorts.first
308
- expect(sort).to be_a Nodes::Sort
309
- expect(sort.name).to eq 'id'
310
- expect(sort.dir).to eq 'desc'
311
- expect(@s.result.options).to eq({ :sort => { '_id' => -1 } })
312
- end
313
-
314
- it 'creates sorts based on a single attribute and uppercase direction' do
315
- @s.sorts = 'id DESC'
316
- expect(@s.sorts.size).to eq(1)
317
- sort = @s.sorts.first
318
- expect(sort).to be_a Nodes::Sort
319
- expect(sort.name).to eq 'id'
320
- expect(sort.dir).to eq 'desc'
321
- expect(@s.result.options).to eq({ :sort => { '_id' => -1 } })
322
- end
323
-
324
- it 'creates sorts based on a single attribute and without direction' do
325
- @s.sorts = 'id'
326
- expect(@s.sorts.size).to eq(1)
327
- sort = @s.sorts.first
328
- expect(sort).to be_a Nodes::Sort
329
- expect(sort.name).to eq 'id'
330
- expect(sort.dir).to eq 'asc'
331
- expect(@s.result.options).to eq({ :sort => { '_id' => 1 } })
332
- end
333
-
334
- it 'creates sorts based on multiple attributes/directions in array format' do
335
- @s.sorts = ['id desc', { :name => 'name', :dir => 'asc' }]
336
- expect(@s.sorts.size).to eq(2)
337
- sort1, sort2 = @s.sorts
338
- expect(sort1).to be_a Nodes::Sort
339
- expect(sort1.name).to eq 'id'
340
- expect(sort1.dir).to eq 'desc'
341
- expect(sort2).to be_a Nodes::Sort
342
- expect(sort2.name).to eq 'name'
343
- expect(sort2.dir).to eq 'asc'
344
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
345
- end
346
-
347
- it 'creates sorts based on multiple attributes and uppercase directions in array format' do
348
- @s.sorts = ['id DESC', { :name => 'name', :dir => 'ASC' }]
349
- expect(@s.sorts.size).to eq(2)
350
- sort1, sort2 = @s.sorts
351
- expect(sort1).to be_a Nodes::Sort
352
- expect(sort1.name).to eq 'id'
353
- expect(sort1.dir).to eq 'desc'
354
- expect(sort2).to be_a Nodes::Sort
355
- expect(sort2.name).to eq 'name'
356
- expect(sort2.dir).to eq 'asc'
357
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
358
- end
359
-
360
- it 'creates sorts based on multiple attributes and different directions in array format' do
361
- @s.sorts = ['id DESC', { name: 'name', dir: nil }]
362
- expect(@s.sorts.size).to eq(2)
363
- sort1, sort2 = @s.sorts
364
- expect(sort1).to be_a Nodes::Sort
365
- expect(sort1.name).to eq 'id'
366
- expect(sort1.dir).to eq 'desc'
367
- expect(sort2).to be_a Nodes::Sort
368
- expect(sort2.name).to eq 'name'
369
- expect(sort2.dir).to eq 'asc'
370
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
371
- end
372
-
373
- it 'creates sorts based on multiple attributes/directions in hash format' do
374
- @s.sorts = {
375
- '0' => { :name => 'id', :dir => 'desc' },
376
- '1' => { :name => 'name', :dir => 'asc' }
377
- }
378
- expect(@s.sorts.size).to eq(2)
379
- expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
380
- id_sort = @s.sorts.detect { |s| s.name == 'id' }
381
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
382
- expect(id_sort.dir).to eq 'desc'
383
- expect(name_sort.dir).to eq 'asc'
384
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
385
- end
386
-
387
- it 'creates sorts based on multiple attributes and uppercase directions in hash format' do
388
- @s.sorts = {
389
- '0' => { :name => 'id', :dir => 'DESC' },
390
- '1' => { :name => 'name', :dir => 'ASC' }
391
- }
392
- expect(@s.sorts.size).to eq(2)
393
- expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
394
- id_sort = @s.sorts.detect { |s| s.name == 'id' }
395
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
396
- expect(id_sort.dir).to eq 'desc'
397
- expect(name_sort.dir).to eq 'asc'
398
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
399
- end
400
-
401
- it 'creates sorts based on multiple attributes and different directions in hash format' do
402
- @s.sorts = {
403
- '0' => { :name => 'id', :dir => 'DESC' },
404
- '1' => { :name => 'name', :dir => nil }
405
- }
406
- expect(@s.sorts.size).to eq(2)
407
- expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
408
- id_sort = @s.sorts.detect { |s| s.name == 'id' }
409
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
410
- expect(id_sort.dir).to eq 'desc'
411
- expect(name_sort.dir).to eq 'asc'
412
- expect(@s.result.options).to eq({ :sort=>{"_id"=>-1, "name"=>1} })
413
- end
414
-
415
- it 'overrides existing sort' do
416
- @s.sorts = 'id asc'
417
- expect(@s.result.first.id.to_s).to eq Person.min(:id).to_s
418
- end
419
- end
420
-
421
- describe '#method_missing' do
422
- before do
423
- @s = Search.new(Person)
424
- end
425
-
426
- it 'raises NoMethodError when sent an invalid attribute' do
427
- expect { @s.blah }.to raise_error NoMethodError
428
- end
429
-
430
- it 'sets condition attributes when sent valid attributes' do
431
- @s.name_eq = 'Ernie'
432
- expect(@s.name_eq).to eq 'Ernie'
433
- end
434
-
435
- context 'with joins' do
436
- before { pending 'not implemented for mongoid' }
437
- it 'allows chaining to access nested conditions' do
438
- @s.groupings = [
439
- { :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' }
440
- ]
441
- expect(@s.groupings.first.children_name_eq).to eq 'Ernie'
442
- end
443
- end
444
- end
445
- end
446
- end
@@ -1,6 +0,0 @@
1
- test:
2
- sessions:
3
- default:
4
- database: ransack_mongoid_test
5
- hosts:
6
- - localhost:27017