where_lower 0.3.0 → 0.3.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 +4 -4
- data/.gitignore +11 -1
- data/.rubocop.yml +856 -0
- data/.travis.yml +23 -12
- data/Appraisals +14 -9
- data/CHANGELOG.md +59 -10
- data/Gemfile +1 -1
- data/README.md +17 -20
- data/Rakefile +5 -2
- data/gemfiles/rails_4_0.gemfile +7 -0
- data/gemfiles/{rails3_1.gemfile → rails_4_1.gemfile} +2 -2
- data/gemfiles/{rails3_2.gemfile → rails_4_2.gemfile} +2 -2
- data/gemfiles/{rails4_0.gemfile → rails_5_0.gemfile} +2 -2
- data/lib/where_lower.rb +5 -5
- data/lib/where_lower/active_record_extension.rb +22 -1
- data/lib/where_lower/base.rb +29 -7
- data/lib/where_lower/scope_spawner.rb +69 -33
- data/lib/where_lower/version.rb +9 -1
- data/spec/spec_helper.rb +21 -16
- data/spec/where_lower_spec.rb +549 -300
- data/where_lower.gemspec +21 -8
- metadata +95 -42
data/lib/where_lower/version.rb
CHANGED
@@ -1,3 +1,11 @@
|
|
1
1
|
module WhereLower
|
2
|
-
|
2
|
+
# String form of version, to be parsed by Gem::Version
|
3
|
+
VERSION = "0.3.1"
|
4
|
+
|
5
|
+
# Return a version object instead of just a string for easier comparison
|
6
|
+
#
|
7
|
+
# @return [Gem::Version]
|
8
|
+
def self.version
|
9
|
+
Gem::Version.new(VERSION)
|
10
|
+
end
|
3
11
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
if ENV["TRAVIS"]
|
2
|
-
require
|
3
|
-
Coveralls.wear!(
|
2
|
+
require "coveralls"
|
3
|
+
Coveralls.wear!("rails")
|
4
4
|
end
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "active_record"
|
7
|
+
require "where_lower"
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
9
|
+
require "database_cleaner"
|
10
|
+
require "logger"
|
11
|
+
|
12
|
+
require "rspec"
|
13
|
+
require "rspec/its"
|
11
14
|
|
12
15
|
# ActiveRecord::Base.logger = Logger.new(STDOUT) # for easier debugging
|
13
16
|
|
@@ -27,19 +30,19 @@ end
|
|
27
30
|
|
28
31
|
# connect
|
29
32
|
ActiveRecord::Base.establish_connection(
|
30
|
-
:
|
31
|
-
:
|
33
|
+
adapter: "sqlite3",
|
34
|
+
database: ":memory:",
|
32
35
|
)
|
33
36
|
|
34
37
|
# create tables
|
35
|
-
ActiveRecord::Schema.define(:
|
38
|
+
ActiveRecord::Schema.define(version: 1) do
|
36
39
|
create_table :parents do |t|
|
37
40
|
t.string :name
|
38
41
|
t.text :description
|
39
42
|
t.integer :age, null: false, default: 0
|
40
43
|
t.boolean :is_minecraft_lover, default: true
|
41
44
|
|
42
|
-
t.timestamps
|
45
|
+
t.timestamps(null: false)
|
43
46
|
end
|
44
47
|
|
45
48
|
create_table :children do |t|
|
@@ -50,7 +53,7 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
50
53
|
|
51
54
|
t.integer :parent_id
|
52
55
|
|
53
|
-
t.timestamps
|
56
|
+
t.timestamps(null: false)
|
54
57
|
end
|
55
58
|
|
56
59
|
create_table :grand_children do |t|
|
@@ -61,13 +64,15 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
61
64
|
|
62
65
|
t.integer :child_id
|
63
66
|
|
64
|
-
t.timestamps
|
67
|
+
t.timestamps(null: false)
|
65
68
|
end
|
66
69
|
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
self.
|
71
|
+
module ActiveRecord
|
72
|
+
class Base
|
73
|
+
def self.silent_set_table_name(name)
|
74
|
+
self.table_name = name
|
75
|
+
end
|
71
76
|
end
|
72
77
|
end
|
73
78
|
|
@@ -76,7 +81,7 @@ end
|
|
76
81
|
class Parent < ActiveRecord::Base
|
77
82
|
has_many :children, inverse_of: :parent
|
78
83
|
|
79
|
-
scope :latest_first, proc { order(
|
84
|
+
scope :latest_first, proc { order("created_at DESC") }
|
80
85
|
def self.earliest_first
|
81
86
|
order(:created_at)
|
82
87
|
end
|
data/spec/where_lower_spec.rb
CHANGED
@@ -1,504 +1,753 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe WhereLower do
|
4
|
+
let(:parent_name) { "Parent" }
|
5
|
+
let(:parent_name2) { "Parent #10" }
|
6
|
+
let(:parent_name3) { "Parent #20" }
|
7
|
+
let(:parent_description) { "I need a Medic!" }
|
8
|
+
let(:parent_description2) { "I need a Job!" }
|
4
9
|
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
let(:
|
8
|
-
let(:
|
9
|
-
let(:
|
10
|
+
let(:child_name) { "Child" }
|
11
|
+
let(:child_name2) { "Child #10" }
|
12
|
+
let(:child_name3) { "Child #20" }
|
13
|
+
let(:child_description) { "I need a Power Ranger!" }
|
14
|
+
let(:child_description2) { "I need a Pokemon!" }
|
10
15
|
|
11
|
-
let(:
|
12
|
-
let(:
|
13
|
-
let(:child_name3) { 'Child #20' }
|
14
|
-
let(:child_description) { 'I need a Power Ranger!' }
|
15
|
-
let(:child_description2) { 'I need a Pokemon!' }
|
16
|
-
|
17
|
-
let(:grand_child_name) { 'Grand Child' }
|
18
|
-
let(:grand_child_name2) { 'Grand Child #10' }
|
16
|
+
let(:grand_child_name) { "Grand Child" }
|
17
|
+
let(:grand_child_name2) { "Grand Child #10" }
|
19
18
|
|
20
19
|
let!(:parent) do
|
21
|
-
Parent.create!(
|
22
|
-
|
20
|
+
Parent.create!(
|
21
|
+
name: parent_name,
|
22
|
+
description: parent_description,
|
23
|
+
age: 40,
|
24
|
+
is_minecraft_lover: false,
|
25
|
+
created_at: 40.years.ago,
|
26
|
+
)
|
23
27
|
end
|
24
28
|
let!(:child) do
|
25
|
-
Child.create!(
|
26
|
-
|
29
|
+
Child.create!(
|
30
|
+
name: child_name,
|
31
|
+
description: child_description,
|
32
|
+
age: 18,
|
33
|
+
is_minecraft_lover: true,
|
34
|
+
created_at: 18.years.ago,
|
35
|
+
parent: parent,
|
36
|
+
)
|
27
37
|
end
|
28
38
|
let!(:grand_child) do
|
29
|
-
GrandChild.create!(
|
30
|
-
|
39
|
+
GrandChild.create!(
|
40
|
+
name: grand_child_name,
|
41
|
+
description: child_description,
|
42
|
+
age: 1,
|
43
|
+
is_minecraft_lover: false,
|
44
|
+
created_at: 1.year.ago,
|
45
|
+
child: child,
|
46
|
+
)
|
31
47
|
end
|
32
48
|
|
33
|
-
describe
|
34
|
-
describe
|
35
|
-
describe
|
49
|
+
describe "finding records with condition(s) for columns inside the model table" do
|
50
|
+
describe "finding record using string column" do
|
51
|
+
describe "with type string" do
|
36
52
|
before do
|
37
|
-
Parent.
|
38
|
-
|
53
|
+
expect(Parent.
|
54
|
+
where(name: parent_name)).
|
55
|
+
to_not be_empty
|
56
|
+
expect(Parent.
|
57
|
+
where(name: parent_name2)).
|
58
|
+
to be_empty
|
39
59
|
end
|
40
60
|
|
41
|
-
it
|
42
|
-
Parent.
|
43
|
-
|
61
|
+
it "works like where" do
|
62
|
+
expect(Parent.
|
63
|
+
where_lower(name: parent_name)).
|
64
|
+
to_not be_empty
|
65
|
+
expect(Parent.
|
66
|
+
where_lower(name: parent_name2)).
|
67
|
+
to be_empty
|
44
68
|
end
|
45
|
-
it
|
46
|
-
Parent.
|
47
|
-
|
69
|
+
it "works like where case insensitively" do
|
70
|
+
expect(Parent.
|
71
|
+
where_lower(name: parent_name.swapcase)).
|
72
|
+
to_not be_empty
|
73
|
+
expect(Parent.
|
74
|
+
where_lower(name: parent_name2.swapcase)).
|
75
|
+
to be_empty
|
48
76
|
end
|
49
77
|
end
|
50
78
|
|
51
|
-
describe
|
79
|
+
describe "with type text" do
|
52
80
|
before do
|
53
|
-
Parent.
|
54
|
-
|
81
|
+
expect(Parent.
|
82
|
+
where(description: parent_description)).
|
83
|
+
to_not be_empty
|
84
|
+
expect(Parent.
|
85
|
+
where(description: parent_description2)).
|
86
|
+
to be_empty
|
55
87
|
end
|
56
88
|
|
57
|
-
it
|
58
|
-
Parent.
|
59
|
-
|
89
|
+
it "works like where" do
|
90
|
+
expect(Parent.
|
91
|
+
where_lower(description: parent_description)).
|
92
|
+
to_not be_empty
|
93
|
+
expect(Parent.
|
94
|
+
where_lower(description: parent_description2)).
|
95
|
+
to be_empty
|
60
96
|
end
|
61
|
-
it
|
62
|
-
Parent.
|
63
|
-
|
97
|
+
it "works like where case insensitively" do
|
98
|
+
expect(Parent.
|
99
|
+
where_lower(description: parent_description.swapcase)).
|
100
|
+
to_not be_empty
|
101
|
+
expect(Parent.
|
102
|
+
where_lower(description: parent_description2.swapcase)).
|
103
|
+
to be_empty
|
64
104
|
end
|
65
105
|
end
|
66
106
|
|
67
|
-
describe
|
68
|
-
describe
|
107
|
+
describe "with different types of values in conditions" do
|
108
|
+
describe "with Range" do
|
69
109
|
before do
|
70
|
-
Parent.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
it
|
79
|
-
Parent.
|
80
|
-
|
110
|
+
expect(Parent.
|
111
|
+
where(name: ("Parens".."Parenu"))).
|
112
|
+
to_not be_empty
|
113
|
+
expect(Parent.
|
114
|
+
where(name: ("Parenu".."Parenv"))).
|
115
|
+
to be_empty
|
116
|
+
end
|
117
|
+
|
118
|
+
it "works like where" do
|
119
|
+
expect(Parent.
|
120
|
+
where_lower(name: ("Parens".."Parenu"))).
|
121
|
+
to_not be_empty
|
122
|
+
expect(Parent.
|
123
|
+
where_lower(name: ("Parenu".."Parenv"))).
|
124
|
+
to be_empty
|
125
|
+
end
|
126
|
+
it "works like where case insensitively" do
|
127
|
+
expect(Parent.
|
128
|
+
where_lower(name: (("Parens".swapcase)..("Parenu".swapcase)))).
|
129
|
+
to_not be_empty
|
130
|
+
expect(Parent.
|
131
|
+
where_lower(name: (("Parenu".swapcase)..("Parenv".swapcase)))).
|
132
|
+
to be_empty
|
81
133
|
end
|
82
134
|
end
|
83
135
|
|
84
|
-
describe
|
136
|
+
describe "with Array" do
|
85
137
|
before do
|
86
|
-
Parent.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
Parent.
|
138
|
+
expect(Parent.
|
139
|
+
where(name: [parent_name, parent_name2])).
|
140
|
+
to_not be_empty
|
141
|
+
expect(Parent.
|
142
|
+
where(name: [parent_name2, parent_name3])).
|
143
|
+
to be_empty
|
144
|
+
end
|
145
|
+
|
146
|
+
it "works like where" do
|
147
|
+
expect(Parent.
|
148
|
+
where_lower(name: [parent_name, parent_name2])).
|
149
|
+
to_not be_empty
|
150
|
+
expect(Parent.
|
151
|
+
where_lower(name: [parent_name2, parent_name3])).
|
152
|
+
to be_empty
|
153
|
+
expect(Parent.
|
154
|
+
where_lower(name: [])).
|
155
|
+
to be_empty
|
156
|
+
end
|
157
|
+
it "works like where case insensitively" do
|
158
|
+
expect(Parent.
|
159
|
+
where_lower(name: [parent_name.swapcase, parent_name2.swapcase])).
|
160
|
+
to_not be_empty
|
161
|
+
expect(Parent.
|
162
|
+
where_lower(name: [parent_name2.swapcase, parent_name3.swapcase])).
|
163
|
+
to be_empty
|
164
|
+
expect(Parent.
|
165
|
+
where_lower(name: [])).
|
166
|
+
to be_empty
|
99
167
|
end
|
100
168
|
end
|
101
169
|
|
102
|
-
describe
|
103
|
-
context
|
170
|
+
describe "with nil" do
|
171
|
+
context "when record with nil value does not exist" do
|
104
172
|
before do
|
105
|
-
Parent.where(name: nil).
|
173
|
+
expect(Parent.where(name: nil)).to be_empty
|
106
174
|
end
|
107
175
|
|
108
|
-
it
|
109
|
-
Parent.where_lower(name: nil).
|
176
|
+
it "works like where" do
|
177
|
+
expect(Parent.where_lower(name: nil)).to be_empty
|
110
178
|
end
|
111
179
|
end
|
112
|
-
context
|
180
|
+
context "when record with nil value does exist" do
|
113
181
|
before do
|
114
182
|
Parent.create!(name: nil)
|
115
183
|
end
|
116
184
|
|
117
185
|
before do
|
118
|
-
Parent.where(name: nil).
|
186
|
+
expect(Parent.where(name: nil)).to_not be_empty
|
119
187
|
end
|
120
188
|
|
121
|
-
it
|
122
|
-
Parent.where_lower(name: nil).
|
189
|
+
it "works like where" do
|
190
|
+
expect(Parent.where_lower(name: nil)).to_not be_empty
|
123
191
|
end
|
124
192
|
end
|
125
193
|
end
|
126
194
|
|
127
|
-
describe
|
128
|
-
it
|
195
|
+
describe "with query injection" do
|
196
|
+
it "prevents injection" do
|
129
197
|
expect do
|
130
|
-
Parent.where_lower(name: "
|
198
|
+
Parent.where_lower(name: %Q|"); truncate table parents|)
|
131
199
|
end.to_not change(Parent, :count)
|
132
200
|
end
|
133
201
|
end
|
134
202
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
203
|
+
describe "with chaining" do
|
204
|
+
it "can be chained with where" do
|
205
|
+
expect(Parent.where_lower(name: parent_name).
|
206
|
+
where(description: parent_description)).
|
207
|
+
to_not be_empty
|
139
208
|
end
|
140
209
|
|
141
|
-
it
|
142
|
-
Parent.where_lower(name: parent_name).
|
210
|
+
it "can be chained with where_lower" do
|
211
|
+
expect(Parent.where_lower(name: parent_name).
|
212
|
+
where_lower(description: parent_description)).
|
213
|
+
to_not be_empty
|
143
214
|
end
|
144
215
|
|
145
|
-
it
|
146
|
-
Parent.where_lower(name: parent_name).order(:description).
|
216
|
+
it "can be chained with order" do
|
217
|
+
expect(Parent.where_lower(name: parent_name).order(:description)).
|
218
|
+
to_not be_empty
|
147
219
|
end
|
148
220
|
|
149
|
-
|
150
|
-
|
151
|
-
|
221
|
+
it "can be chained with name scope" do
|
222
|
+
expect(Parent.where_lower(name: parent_name).latest_first).
|
223
|
+
to_not be_empty
|
152
224
|
end
|
153
|
-
it
|
154
|
-
Parent.where_lower(name: parent_name).earliest_first.
|
225
|
+
it "can be chained with class method scope" do
|
226
|
+
expect(Parent.where_lower(name: parent_name).earliest_first).
|
227
|
+
to_not be_empty
|
155
228
|
end
|
156
229
|
end
|
157
230
|
end
|
158
231
|
end
|
159
232
|
|
160
|
-
describe
|
161
|
-
describe
|
233
|
+
describe "finding record using non string columns" do
|
234
|
+
describe "with type integer" do
|
162
235
|
before do
|
163
|
-
Parent.where(age: parent.age).
|
164
|
-
|
236
|
+
expect(Parent.where(age: parent.age)).
|
237
|
+
to_not be_empty
|
238
|
+
expect(Parent.where(age: parent.age + 1)).
|
239
|
+
to be_empty
|
165
240
|
end
|
166
241
|
|
167
|
-
it
|
168
|
-
Parent.where_lower(age: parent.age).
|
169
|
-
|
242
|
+
it "works like where" do
|
243
|
+
expect(Parent.where_lower(age: parent.age)).
|
244
|
+
to_not be_empty
|
245
|
+
expect(Parent.where_lower(age: parent.age + 1)).
|
246
|
+
to be_empty
|
170
247
|
end
|
171
248
|
end
|
172
249
|
|
173
|
-
describe
|
250
|
+
describe "with type boolean" do
|
174
251
|
before do
|
175
|
-
Parent.where(is_minecraft_lover: parent.is_minecraft_lover).
|
176
|
-
|
252
|
+
expect(Parent.where(is_minecraft_lover: parent.is_minecraft_lover)).
|
253
|
+
to_not be_empty
|
254
|
+
expect(Parent.where(is_minecraft_lover: !parent.is_minecraft_lover)).
|
255
|
+
to be_empty
|
177
256
|
end
|
178
257
|
|
179
|
-
it
|
180
|
-
Parent.where_lower(is_minecraft_lover: parent.is_minecraft_lover).
|
181
|
-
|
258
|
+
it "works like where" do
|
259
|
+
expect(Parent.where_lower(is_minecraft_lover: parent.is_minecraft_lover)).
|
260
|
+
to_not be_empty
|
261
|
+
expect(Parent.where_lower(is_minecraft_lover: !parent.is_minecraft_lover)).
|
262
|
+
to be_empty
|
182
263
|
end
|
183
264
|
end
|
184
265
|
end
|
185
266
|
end
|
186
267
|
|
187
|
-
describe
|
188
|
-
describe
|
189
|
-
describe
|
190
|
-
describe
|
268
|
+
describe "finding records with condition(s) for columns outside the model table" do
|
269
|
+
describe "using string as hash key" do
|
270
|
+
describe "finding record using string column" do
|
271
|
+
describe "with type string" do
|
191
272
|
before do
|
192
|
-
Parent.joins(:children).
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
it
|
201
|
-
Parent.joins(:children).
|
202
|
-
|
273
|
+
expect(Parent.joins(:children).
|
274
|
+
where("children.name" => child_name)).
|
275
|
+
to_not be_empty
|
276
|
+
expect(Parent.joins(:children).
|
277
|
+
where("children.name" => child_name2)).
|
278
|
+
to be_empty
|
279
|
+
end
|
280
|
+
|
281
|
+
it "works like where" do
|
282
|
+
expect(Parent.joins(:children).
|
283
|
+
where_lower("children.name" => child_name)).
|
284
|
+
to_not be_empty
|
285
|
+
expect(Parent.joins(:children).
|
286
|
+
where_lower("children.name" => child_name2)).
|
287
|
+
to be_empty
|
288
|
+
end
|
289
|
+
it "works like where case insensitively" do
|
290
|
+
expect(Parent.joins(:children).
|
291
|
+
where_lower("children.name" => child_name.swapcase)).
|
292
|
+
to_not be_empty
|
293
|
+
expect(Parent.joins(:children).
|
294
|
+
where_lower("children.name" => child_name2.swapcase)).
|
295
|
+
to be_empty
|
203
296
|
end
|
204
297
|
end
|
205
298
|
|
206
|
-
describe
|
299
|
+
describe "with type text" do
|
207
300
|
before do
|
208
|
-
Parent.joins(:children).
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
it
|
217
|
-
Parent.joins(:children).
|
218
|
-
|
301
|
+
expect(Parent.joins(:children).
|
302
|
+
where("children.description" => child_description)).
|
303
|
+
to_not be_empty
|
304
|
+
expect(Parent.joins(:children).
|
305
|
+
where("children.description" => child_description2)).
|
306
|
+
to be_empty
|
307
|
+
end
|
308
|
+
|
309
|
+
it "works like where" do
|
310
|
+
expect(Parent.joins(:children).
|
311
|
+
where_lower("children.description" => child_description)).
|
312
|
+
to_not be_empty
|
313
|
+
expect(Parent.joins(:children).
|
314
|
+
where_lower("children.description" => child_description2)).
|
315
|
+
to be_empty
|
316
|
+
end
|
317
|
+
it "works like where case insensitively" do
|
318
|
+
expect(Parent.joins(:children).
|
319
|
+
where_lower("children.description" => child_description.swapcase)).
|
320
|
+
to_not be_empty
|
321
|
+
expect(Parent.joins(:children).
|
322
|
+
where_lower("children.description" => child_description2.swapcase)).
|
323
|
+
to be_empty
|
219
324
|
end
|
220
325
|
end
|
221
326
|
|
222
|
-
describe
|
223
|
-
describe
|
327
|
+
describe "with different types of values in conditions" do
|
328
|
+
describe "with Range" do
|
224
329
|
before do
|
225
|
-
Parent.joins(:children).
|
226
|
-
|
330
|
+
expect(Parent.joins(:children).
|
331
|
+
where("children.name" => ("Chilc".."Chile"))).
|
332
|
+
to_not be_empty
|
333
|
+
expect(Parent.joins(:children).
|
334
|
+
where("children.name" => ("Chile".."Chilf"))).
|
335
|
+
to be_empty
|
227
336
|
end
|
228
337
|
|
229
|
-
it
|
230
|
-
Parent.joins(:children).
|
231
|
-
|
338
|
+
it "works like where" do
|
339
|
+
expect(Parent.joins(:children).
|
340
|
+
where_lower("children.name" => ("Chilc".."Chile"))).
|
341
|
+
to_not be_empty
|
342
|
+
expect(Parent.joins(:children).
|
343
|
+
where_lower("children.name" => ("Chile".."Chilf"))).
|
344
|
+
to be_empty
|
232
345
|
end
|
233
|
-
it
|
234
|
-
Parent.joins(:children).
|
235
|
-
|
346
|
+
it "works like where case insensitively" do
|
347
|
+
expect(Parent.joins(:children).
|
348
|
+
where_lower("children.name" => (("Chilc".swapcase)..("Chile".swapcase)))).
|
349
|
+
to_not be_empty
|
350
|
+
expect(Parent.joins(:children).
|
351
|
+
where_lower("children.name" => (("Chile".swapcase)..("Chilf".swapcase)))).
|
352
|
+
to be_empty
|
236
353
|
end
|
237
354
|
end
|
238
355
|
|
239
|
-
describe
|
356
|
+
describe "with Array" do
|
240
357
|
before do
|
241
|
-
Parent.joins(:children).
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
Parent.joins(:children).
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
358
|
+
expect(Parent.joins(:children).
|
359
|
+
where("children.name" => [child_name, child_name2])).
|
360
|
+
to_not be_empty
|
361
|
+
expect(Parent.joins(:children).
|
362
|
+
where("children.name" => [child_name2, child_name3])).
|
363
|
+
to be_empty
|
364
|
+
end
|
365
|
+
|
366
|
+
it "works like where" do
|
367
|
+
expect(Parent.joins(:children).
|
368
|
+
where_lower("children.name" => [child_name, child_name2])).
|
369
|
+
to_not be_empty
|
370
|
+
expect(Parent.joins(:children).
|
371
|
+
where_lower("children.name" => [child_name2, child_name3])).
|
372
|
+
to be_empty
|
373
|
+
expect(Parent.joins(:children).
|
374
|
+
where_lower("children.name" => [])).
|
375
|
+
to be_empty
|
376
|
+
end
|
377
|
+
it "works like where case insensitively" do
|
378
|
+
expect(Parent.joins(:children).
|
379
|
+
where_lower("children.name" => [child_name.swapcase, child_name2.swapcase])).
|
380
|
+
to_not be_empty
|
381
|
+
expect(Parent.joins(:children).
|
382
|
+
where_lower("children.name" => [child_name2.swapcase, child_name3.swapcase])).
|
383
|
+
to be_empty
|
384
|
+
expect(Parent.joins(:children).
|
385
|
+
where_lower("children.name" => [])).
|
386
|
+
to be_empty
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe "with nil" do
|
391
|
+
context "when record with nil value does not exist" do
|
259
392
|
before do
|
260
|
-
Parent.joins(:children).
|
393
|
+
expect(Parent.joins(:children).
|
394
|
+
where("children.name" => nil)).to be_empty
|
261
395
|
end
|
262
396
|
|
263
|
-
it
|
264
|
-
Parent.joins(:children).
|
397
|
+
it "works like where" do
|
398
|
+
expect(Parent.joins(:children).
|
399
|
+
where_lower("children.name" => nil)).to be_empty
|
265
400
|
end
|
266
401
|
end
|
267
|
-
context
|
402
|
+
context "when record with nil value does exist" do
|
268
403
|
before do
|
269
404
|
Child.create!(name: nil, parent: parent)
|
270
405
|
end
|
271
406
|
|
272
407
|
before do
|
273
|
-
Parent.joins(:children).
|
408
|
+
expect(Parent.joins(:children).
|
409
|
+
where("children.name" => nil)).to_not be_empty
|
274
410
|
end
|
275
411
|
|
276
|
-
it
|
277
|
-
Parent.joins(:children).
|
412
|
+
it "works like where" do
|
413
|
+
expect(Parent.joins(:children).
|
414
|
+
where_lower("children.name" => nil)).to_not be_empty
|
278
415
|
end
|
279
416
|
end
|
280
417
|
end
|
281
418
|
|
282
|
-
describe
|
283
|
-
it
|
419
|
+
describe "with query injection" do
|
420
|
+
it "prevents injection" do
|
284
421
|
expect do
|
285
|
-
Parent.joins(:children).
|
422
|
+
Parent.joins(:children).
|
423
|
+
where_lower("children.name" => %Q|"); truncate table parents|)
|
286
424
|
end.to_not change(Child, :count)
|
287
425
|
end
|
288
426
|
end
|
289
427
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
428
|
+
describe "with chaining" do
|
429
|
+
it "can be chained with where" do
|
430
|
+
expect(Parent.joins(:children).
|
431
|
+
where_lower("children.name" => child_name).
|
432
|
+
where("children.description" => child_description)).
|
433
|
+
to_not be_empty
|
294
434
|
end
|
295
435
|
|
296
|
-
it
|
297
|
-
Parent.joins(:children).
|
436
|
+
it "can be chained with where_lower" do
|
437
|
+
expect(Parent.joins(:children).
|
438
|
+
where_lower("children.name" => child_name).
|
439
|
+
where_lower("children.description" => child_description)).
|
440
|
+
to_not be_empty
|
298
441
|
end
|
299
442
|
|
300
|
-
it
|
301
|
-
Parent.joins(:children).
|
443
|
+
it "can be chained with order" do
|
444
|
+
expect(Parent.joins(:children).
|
445
|
+
where_lower("children.name" => child_name).order("children.description")).
|
446
|
+
to_not be_empty
|
302
447
|
end
|
303
448
|
|
304
|
-
|
305
|
-
|
306
|
-
|
449
|
+
it "can be chained with name scope" do
|
450
|
+
expect(Parent.joins(:children).
|
451
|
+
where_lower("children.name" => child_name).latest_first).
|
452
|
+
to_not be_empty
|
307
453
|
end
|
308
|
-
it
|
309
|
-
Parent.joins(:children).
|
454
|
+
it "can be chained with class method scope" do
|
455
|
+
expect(Parent.joins(:children).
|
456
|
+
where_lower("children.name" => child_name).earliest_first).
|
457
|
+
to_not be_empty
|
310
458
|
end
|
311
459
|
end
|
312
460
|
end
|
313
461
|
end
|
314
462
|
|
315
|
-
describe
|
316
|
-
describe
|
463
|
+
describe "finding record using non string columns" do
|
464
|
+
describe "with type integer" do
|
317
465
|
before do
|
318
|
-
Parent.joins(:children).
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
466
|
+
expect(Parent.joins(:children).
|
467
|
+
where("children.age" => child.age)).
|
468
|
+
to_not be_empty
|
469
|
+
expect(Parent.joins(:children).
|
470
|
+
where("children.age" => child.age + 1)).
|
471
|
+
to be_empty
|
472
|
+
end
|
473
|
+
|
474
|
+
it "works like where" do
|
475
|
+
expect(Parent.joins(:children).
|
476
|
+
where_lower("children.age" => child.age)).
|
477
|
+
to_not be_empty
|
478
|
+
expect(Parent.joins(:children).
|
479
|
+
where_lower("children.age" => child.age + 1)).
|
480
|
+
to be_empty
|
325
481
|
end
|
326
482
|
end
|
327
483
|
|
328
|
-
describe
|
484
|
+
describe "with type boolean" do
|
329
485
|
before do
|
330
|
-
Parent.joins(:children).
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
486
|
+
expect(Parent.joins(:children).
|
487
|
+
where("children.is_minecraft_lover" => child.is_minecraft_lover)).
|
488
|
+
to_not be_empty
|
489
|
+
expect(Parent.joins(:children).
|
490
|
+
where("children.is_minecraft_lover" => !child.is_minecraft_lover)).
|
491
|
+
to be_empty
|
492
|
+
end
|
493
|
+
|
494
|
+
it "works like where" do
|
495
|
+
expect(Parent.joins(:children).
|
496
|
+
where_lower("children.is_minecraft_lover" => child.is_minecraft_lover)).
|
497
|
+
to_not be_empty
|
498
|
+
expect(Parent.joins(:children).
|
499
|
+
where_lower("children.is_minecraft_lover" => !child.is_minecraft_lover)).
|
500
|
+
to be_empty
|
337
501
|
end
|
338
502
|
end
|
339
503
|
end
|
340
504
|
end
|
341
505
|
|
342
|
-
describe
|
343
|
-
describe
|
344
|
-
describe
|
506
|
+
describe "using nested hash" do
|
507
|
+
describe "finding record using string column" do
|
508
|
+
describe "with type string" do
|
345
509
|
before do
|
346
|
-
Parent.joins(:children).
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
it
|
355
|
-
Parent.joins(:children).
|
356
|
-
|
510
|
+
expect(Parent.joins(:children).
|
511
|
+
where(children: {name: child_name})).
|
512
|
+
to_not be_empty
|
513
|
+
expect(Parent.joins(:children).
|
514
|
+
where(children: {name: child_name2})).
|
515
|
+
to be_empty
|
516
|
+
end
|
517
|
+
|
518
|
+
it "works like where" do
|
519
|
+
expect(Parent.joins(:children).
|
520
|
+
where_lower(children: {name: child_name})).
|
521
|
+
to_not be_empty
|
522
|
+
expect(Parent.joins(:children).
|
523
|
+
where_lower(children: {name: child_name2})).
|
524
|
+
to be_empty
|
525
|
+
end
|
526
|
+
it "works like where case insensitively" do
|
527
|
+
expect(Parent.joins(:children).
|
528
|
+
where_lower(children: {name: child_name.swapcase})).
|
529
|
+
to_not be_empty
|
530
|
+
expect(Parent.joins(:children).
|
531
|
+
where_lower(children: {name: child_name2.swapcase})).
|
532
|
+
to be_empty
|
357
533
|
end
|
358
534
|
end
|
359
535
|
|
360
|
-
describe
|
536
|
+
describe "with type text" do
|
361
537
|
before do
|
362
|
-
Parent.joins(:children).
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
it
|
371
|
-
Parent.joins(:children).
|
372
|
-
|
538
|
+
expect(Parent.joins(:children).
|
539
|
+
where(children: {description: child_description})).
|
540
|
+
to_not be_empty
|
541
|
+
expect(Parent.joins(:children).
|
542
|
+
where(children: {description: child_description2})).
|
543
|
+
to be_empty
|
544
|
+
end
|
545
|
+
|
546
|
+
it "works like where" do
|
547
|
+
expect(Parent.joins(:children).
|
548
|
+
where_lower(children: {description: child_description})).
|
549
|
+
to_not be_empty
|
550
|
+
expect(Parent.joins(:children).
|
551
|
+
where_lower(children: {description: child_description2})).
|
552
|
+
to be_empty
|
553
|
+
end
|
554
|
+
it "works like where case insensitively" do
|
555
|
+
expect(Parent.joins(:children).
|
556
|
+
where_lower(children: {description: child_description.swapcase})).
|
557
|
+
to_not be_empty
|
558
|
+
expect(Parent.joins(:children).
|
559
|
+
where_lower(children: {description: child_description2.swapcase})).
|
560
|
+
to be_empty
|
373
561
|
end
|
374
562
|
end
|
375
563
|
|
376
|
-
describe
|
377
|
-
describe
|
564
|
+
describe "with different types of values in conditions" do
|
565
|
+
describe "with Range" do
|
378
566
|
before do
|
379
|
-
Parent.joins(:children).
|
380
|
-
|
567
|
+
expect(Parent.joins(:children).
|
568
|
+
where(children: {name: ("Chilc".."Chile")})).
|
569
|
+
to_not be_empty
|
570
|
+
expect(Parent.joins(:children).
|
571
|
+
where(children: {name: ("Chile".."Chilf")})).
|
572
|
+
to be_empty
|
381
573
|
end
|
382
574
|
|
383
|
-
it
|
384
|
-
Parent.joins(:children).
|
385
|
-
|
575
|
+
it "works like where" do
|
576
|
+
expect(Parent.joins(:children).
|
577
|
+
where_lower(children: {name: ("Chilc".."Chile")})).
|
578
|
+
to_not be_empty
|
579
|
+
expect(Parent.joins(:children).
|
580
|
+
where_lower(children: {name: ("Chile".."Chilf")})).
|
581
|
+
to be_empty
|
386
582
|
end
|
387
|
-
it
|
388
|
-
Parent.joins(:children).
|
389
|
-
|
583
|
+
it "works like where case insensitively" do
|
584
|
+
expect(Parent.joins(:children).
|
585
|
+
where_lower(children: {name: (("Chilc".swapcase)..("Chile".swapcase))})).
|
586
|
+
to_not be_empty
|
587
|
+
expect(Parent.joins(:children).
|
588
|
+
where_lower(children: {name: (("Chile".swapcase)..("Chilf".swapcase))})).
|
589
|
+
to be_empty
|
390
590
|
end
|
391
591
|
end
|
392
592
|
|
393
|
-
describe
|
593
|
+
describe "with Array" do
|
394
594
|
before do
|
395
|
-
Parent.joins(:children).
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
Parent.joins(:children).
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
595
|
+
expect(Parent.joins(:children).
|
596
|
+
where(children: {name: [child_name, child_name2]})).
|
597
|
+
to_not be_empty
|
598
|
+
expect(Parent.joins(:children).
|
599
|
+
where(children: {name: [child_name2, child_name3]})).
|
600
|
+
to be_empty
|
601
|
+
end
|
602
|
+
|
603
|
+
it "works like where" do
|
604
|
+
expect(Parent.joins(:children).
|
605
|
+
where_lower(children: {name: [child_name, child_name2]})).
|
606
|
+
to_not be_empty
|
607
|
+
expect(Parent.joins(:children).
|
608
|
+
where_lower(children: {name: [child_name2, child_name3]})).
|
609
|
+
to be_empty
|
610
|
+
expect(Parent.joins(:children).
|
611
|
+
where_lower(children: {name: []})).
|
612
|
+
to be_empty
|
613
|
+
end
|
614
|
+
it "works like where case insensitively" do
|
615
|
+
expect(Parent.joins(:children).
|
616
|
+
where_lower(children: {name: [child_name.swapcase, child_name2.swapcase]})).
|
617
|
+
to_not be_empty
|
618
|
+
expect(Parent.joins(:children).
|
619
|
+
where_lower(children: {name: [child_name2.swapcase, child_name3.swapcase]})).
|
620
|
+
to be_empty
|
621
|
+
expect(Parent.joins(:children).
|
622
|
+
where_lower(children: {name: []})).
|
623
|
+
to be_empty
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
describe "with nil" do
|
628
|
+
context "when record with nil value does not exist" do
|
413
629
|
before do
|
414
|
-
Parent.joins(:children).
|
630
|
+
expect(Parent.joins(:children).
|
631
|
+
where(children: {name: nil})).to be_empty
|
415
632
|
end
|
416
633
|
|
417
|
-
it
|
418
|
-
Parent.joins(:children).
|
634
|
+
it "works like where" do
|
635
|
+
expect(Parent.joins(:children).
|
636
|
+
where_lower(children: {name: nil})).to be_empty
|
419
637
|
end
|
420
638
|
end
|
421
|
-
context
|
639
|
+
context "when record with nil value does exist" do
|
422
640
|
before do
|
423
641
|
Child.create!(name: nil, parent: parent)
|
424
642
|
end
|
425
643
|
|
426
644
|
before do
|
427
|
-
Parent.joins(:children).
|
645
|
+
expect(Parent.joins(:children).
|
646
|
+
where(children: {name: nil})).to_not be_empty
|
428
647
|
end
|
429
648
|
|
430
|
-
it
|
431
|
-
Parent.joins(:children).
|
649
|
+
it "works like where" do
|
650
|
+
expect(Parent.joins(:children).
|
651
|
+
where_lower(children: {name: nil})).to_not be_empty
|
432
652
|
end
|
433
653
|
end
|
434
654
|
end
|
435
655
|
|
436
|
-
describe
|
437
|
-
it
|
656
|
+
describe "with query injection" do
|
657
|
+
it "prevents injection" do
|
438
658
|
expect do
|
439
|
-
Parent.joins(:children).
|
659
|
+
Parent.joins(:children).
|
660
|
+
where_lower(children: {name: %Q|"); truncate table parents|})
|
440
661
|
end.to_not change(Child, :count)
|
441
662
|
end
|
442
663
|
end
|
443
664
|
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
665
|
+
describe "with chaining" do
|
666
|
+
it "can be chained with where" do
|
667
|
+
expect(Parent.joins(:children).
|
668
|
+
where_lower(children: {name: child_name}).
|
669
|
+
where(children: {description: child_description})).
|
670
|
+
to_not be_empty
|
448
671
|
end
|
449
672
|
|
450
|
-
it
|
451
|
-
Parent.joins(:children).
|
673
|
+
it "can be chained with where_lower" do
|
674
|
+
expect(Parent.joins(:children).
|
675
|
+
where_lower(children: {name: child_name}).
|
676
|
+
where_lower(children: {description: child_description})).
|
677
|
+
to_not be_empty
|
452
678
|
end
|
453
679
|
|
454
|
-
it
|
455
|
-
Parent.joins(:children).
|
680
|
+
it "can be chained with order" do
|
681
|
+
expect(Parent.joins(:children).
|
682
|
+
where_lower(children: {name: child_name}).
|
683
|
+
order("children.description")).
|
684
|
+
to_not be_empty
|
456
685
|
end
|
457
686
|
|
458
|
-
|
459
|
-
|
460
|
-
|
687
|
+
it "can be chained with name scope" do
|
688
|
+
expect(Parent.joins(:children).
|
689
|
+
where_lower(children: {name: child_name}).latest_first).
|
690
|
+
to_not be_empty
|
461
691
|
end
|
462
|
-
it
|
463
|
-
Parent.joins(:children).
|
692
|
+
it "can be chained with class method scope" do
|
693
|
+
expect(Parent.joins(:children).
|
694
|
+
where_lower(children: {name: child_name}).earliest_first).
|
695
|
+
to_not be_empty
|
464
696
|
end
|
465
697
|
end
|
466
698
|
end
|
467
699
|
end
|
468
700
|
|
469
|
-
describe
|
470
|
-
describe
|
701
|
+
describe "finding record using non string columns" do
|
702
|
+
describe "with type integer" do
|
471
703
|
before do
|
472
|
-
Parent.joins(:children).
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
704
|
+
expect(Parent.joins(:children).
|
705
|
+
where(children: {age: child.age})).
|
706
|
+
to_not be_empty
|
707
|
+
expect(Parent.joins(:children).
|
708
|
+
where(children: {age: child.age + 1})).
|
709
|
+
to be_empty
|
710
|
+
end
|
711
|
+
|
712
|
+
it "works like where" do
|
713
|
+
expect(Parent.joins(:children).
|
714
|
+
where_lower(children: {age: child.age})).
|
715
|
+
to_not be_empty
|
716
|
+
expect(Parent.joins(:children).
|
717
|
+
where_lower(children: {age: child.age + 1})).
|
718
|
+
to be_empty
|
479
719
|
end
|
480
720
|
end
|
481
721
|
|
482
|
-
describe
|
722
|
+
describe "with type boolean" do
|
483
723
|
before do
|
484
|
-
Parent.joins(:children).
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
724
|
+
expect(Parent.joins(:children).
|
725
|
+
where(children: {is_minecraft_lover: child.is_minecraft_lover})).
|
726
|
+
to_not be_empty
|
727
|
+
expect(Parent.joins(:children).
|
728
|
+
where(children: {is_minecraft_lover: !child.is_minecraft_lover})).
|
729
|
+
to be_empty
|
730
|
+
end
|
731
|
+
|
732
|
+
it "works like where" do
|
733
|
+
expect(Parent.joins(:children).
|
734
|
+
where_lower(children: {is_minecraft_lover: child.is_minecraft_lover})).
|
735
|
+
to_not be_empty
|
736
|
+
expect(Parent.joins(:children).
|
737
|
+
where_lower(children: {is_minecraft_lover: !child.is_minecraft_lover})).
|
738
|
+
to be_empty
|
491
739
|
end
|
492
740
|
end
|
493
741
|
end
|
494
742
|
|
495
|
-
|
496
|
-
|
497
|
-
it 'raises error' do
|
743
|
+
describe "with more than one level deep" do
|
744
|
+
it "raises error" do
|
498
745
|
expect do
|
499
|
-
Parent.joins(children: :grand_children).
|
746
|
+
Parent.joins(children: :grand_children).
|
747
|
+
where_lower(children: {grand_children: {name: grand_child_name}})
|
500
748
|
end.to raise_error(WhereLower::TooDeepNestedConditions)
|
501
749
|
end
|
750
|
+
end
|
502
751
|
end
|
503
752
|
end
|
504
753
|
end
|