pg_search 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop.yml +11 -7
- data/.travis.yml +33 -42
- data/CHANGELOG.md +140 -112
- data/CONTRIBUTING.md +5 -3
- data/Gemfile +6 -4
- data/LICENSE +1 -1
- data/README.md +221 -159
- data/Rakefile +3 -5
- data/lib/pg_search/configuration/association.rb +2 -0
- data/lib/pg_search/configuration/column.rb +2 -0
- data/lib/pg_search/configuration/foreign_column.rb +2 -0
- data/lib/pg_search/configuration.rb +8 -4
- data/lib/pg_search/document.rb +5 -3
- data/lib/pg_search/features/dmetaphone.rb +3 -1
- data/lib/pg_search/features/feature.rb +4 -2
- data/lib/pg_search/features/trigram.rb +31 -5
- data/lib/pg_search/features/tsearch.rb +4 -1
- data/lib/pg_search/features.rb +2 -0
- data/lib/pg_search/migration/dmetaphone_generator.rb +3 -1
- data/lib/pg_search/migration/generator.rb +4 -2
- data/lib/pg_search/migration/multisearch_generator.rb +2 -1
- data/lib/pg_search/migration/templates/create_pg_search_documents.rb.erb +1 -1
- data/lib/pg_search/multisearch/rebuilder.rb +7 -3
- data/lib/pg_search/multisearch.rb +4 -4
- data/lib/pg_search/multisearchable.rb +10 -6
- data/lib/pg_search/normalizer.rb +2 -0
- data/lib/pg_search/railtie.rb +2 -0
- data/lib/pg_search/scope_options.rb +21 -41
- data/lib/pg_search/tasks.rb +3 -0
- data/lib/pg_search/version.rb +3 -1
- data/lib/pg_search.rb +10 -5
- data/pg_search.gemspec +8 -7
- data/spec/integration/associations_spec.rb +103 -101
- data/spec/integration/pagination_spec.rb +9 -7
- data/spec/integration/pg_search_spec.rb +266 -255
- data/spec/integration/single_table_inheritance_spec.rb +16 -15
- data/spec/lib/pg_search/configuration/association_spec.rb +7 -5
- data/spec/lib/pg_search/configuration/column_spec.rb +2 -0
- data/spec/lib/pg_search/configuration/foreign_column_spec.rb +5 -3
- data/spec/lib/pg_search/features/dmetaphone_spec.rb +6 -4
- data/spec/lib/pg_search/features/trigram_spec.rb +39 -12
- data/spec/lib/pg_search/features/tsearch_spec.rb +23 -21
- data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +32 -11
- data/spec/lib/pg_search/multisearch_spec.rb +9 -7
- data/spec/lib/pg_search/multisearchable_spec.rb +68 -27
- data/spec/lib/pg_search/normalizer_spec.rb +7 -5
- data/spec/lib/pg_search_spec.rb +33 -31
- data/spec/spec_helper.rb +3 -1
- data/spec/support/database.rb +16 -20
- data/spec/support/with_model.rb +2 -0
- metadata +13 -30
- data/.rubocop_todo.yml +0 -163
- data/Guardfile +0 -6
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe PgSearch::Multisearchable do
|
@@ -11,6 +13,33 @@ describe PgSearch::Multisearchable do
|
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
16
|
+
with_model :MultisearchableParent do
|
17
|
+
table do |t|
|
18
|
+
t.string :secret
|
19
|
+
end
|
20
|
+
|
21
|
+
model do
|
22
|
+
include PgSearch
|
23
|
+
multisearchable
|
24
|
+
|
25
|
+
has_many :multisearchable_children, dependent: :destroy
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
with_model :MultisearchableChild do
|
30
|
+
table do |t|
|
31
|
+
t.belongs_to :multisearchable_parent, index: false
|
32
|
+
end
|
33
|
+
|
34
|
+
model do
|
35
|
+
belongs_to :multisearchable_parent
|
36
|
+
|
37
|
+
after_destroy do
|
38
|
+
multisearchable_parent.update_attribute(:secret, rand(1000).to_s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
14
43
|
describe "callbacks" do
|
15
44
|
describe "after_create" do
|
16
45
|
let(:record) { ModelThatIsMultisearchable.new }
|
@@ -92,6 +121,18 @@ describe PgSearch::Multisearchable do
|
|
92
121
|
expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
|
93
122
|
expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
94
123
|
end
|
124
|
+
|
125
|
+
it "should remove its document in case of complex associations" do
|
126
|
+
parent = MultisearchableParent.create!
|
127
|
+
|
128
|
+
MultisearchableChild.create!(multisearchable_parent: parent)
|
129
|
+
MultisearchableChild.create!(multisearchable_parent: parent)
|
130
|
+
|
131
|
+
document = parent.pg_search_document
|
132
|
+
|
133
|
+
expect { parent.destroy }.to change(PgSearch::Document, :count).by(-1)
|
134
|
+
expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
135
|
+
end
|
95
136
|
end
|
96
137
|
end
|
97
138
|
|
@@ -104,7 +145,7 @@ describe PgSearch::Multisearchable do
|
|
104
145
|
end
|
105
146
|
|
106
147
|
context "when searching against a single column" do
|
107
|
-
let(:multisearchable_options) { {:
|
148
|
+
let(:multisearchable_options) { { against: :some_content } }
|
108
149
|
let(:text) { "foo bar" }
|
109
150
|
before do
|
110
151
|
allow(record).to receive(:some_content) { text }
|
@@ -118,7 +159,7 @@ describe PgSearch::Multisearchable do
|
|
118
159
|
end
|
119
160
|
|
120
161
|
context "when searching against multiple columns" do
|
121
|
-
let(:multisearchable_options) { {:
|
162
|
+
let(:multisearchable_options) { { against: %i[attr1 attr2] } }
|
122
163
|
before do
|
123
164
|
allow(record).to receive(:attr1) { '1' }
|
124
165
|
allow(record).to receive(:attr2) { '2' }
|
@@ -141,7 +182,7 @@ describe PgSearch::Multisearchable do
|
|
141
182
|
end
|
142
183
|
|
143
184
|
context "when searching against a single column" do
|
144
|
-
let(:multisearchable_options) { {:
|
185
|
+
let(:multisearchable_options) { { against: :some_content } }
|
145
186
|
let(:text) { "foo bar" }
|
146
187
|
before do
|
147
188
|
allow(record).to receive(:some_content) { text }
|
@@ -155,7 +196,7 @@ describe PgSearch::Multisearchable do
|
|
155
196
|
end
|
156
197
|
|
157
198
|
context "when searching against multiple columns" do
|
158
|
-
let(:multisearchable_options) { {:
|
199
|
+
let(:multisearchable_options) { { against: %i[attr1 attr2] } }
|
159
200
|
before do
|
160
201
|
allow(record).to receive(:attr1) { '1' }
|
161
202
|
allow(record).to receive(:attr2) { '2' }
|
@@ -171,7 +212,7 @@ describe PgSearch::Multisearchable do
|
|
171
212
|
context "with additional_attributes" do
|
172
213
|
let(:multisearchable_options) do
|
173
214
|
{
|
174
|
-
:
|
215
|
+
additional_attributes: lambda do |record|
|
175
216
|
{ foo: record.bar }
|
176
217
|
end
|
177
218
|
}
|
@@ -190,7 +231,7 @@ describe PgSearch::Multisearchable do
|
|
190
231
|
context "when selectively updating" do
|
191
232
|
let(:multisearchable_options) do
|
192
233
|
{
|
193
|
-
:
|
234
|
+
update_if: lambda do |record|
|
194
235
|
record.bar?
|
195
236
|
end
|
196
237
|
}
|
@@ -215,7 +256,7 @@ describe PgSearch::Multisearchable do
|
|
215
256
|
|
216
257
|
it "does not update the document" do
|
217
258
|
expect_any_instance_of(PgSearch::Document)
|
218
|
-
.to_not receive(:
|
259
|
+
.to_not receive(:update)
|
219
260
|
|
220
261
|
record.save
|
221
262
|
end
|
@@ -228,7 +269,7 @@ describe PgSearch::Multisearchable do
|
|
228
269
|
|
229
270
|
it "updates the document" do
|
230
271
|
expect_any_instance_of(PgSearch::Document)
|
231
|
-
.to receive(:
|
272
|
+
.to receive(:update)
|
232
273
|
|
233
274
|
record.save
|
234
275
|
end
|
@@ -247,7 +288,7 @@ describe PgSearch::Multisearchable do
|
|
247
288
|
|
248
289
|
model do
|
249
290
|
include PgSearch
|
250
|
-
multisearchable :
|
291
|
+
multisearchable if: ->(record) { record.multisearchable? }
|
251
292
|
end
|
252
293
|
end
|
253
294
|
|
@@ -255,7 +296,7 @@ describe PgSearch::Multisearchable do
|
|
255
296
|
describe "after_create" do
|
256
297
|
describe "saving the record" do
|
257
298
|
context "when the condition is true" do
|
258
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
299
|
+
let(:record) { ModelThatIsMultisearchable.new(multisearchable: true) }
|
259
300
|
|
260
301
|
it "should create a PgSearch::Document record" do
|
261
302
|
expect { record.save! }.to change(PgSearch::Document, :count).by(1)
|
@@ -271,7 +312,7 @@ describe PgSearch::Multisearchable do
|
|
271
312
|
end
|
272
313
|
|
273
314
|
context "when the condition is false" do
|
274
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
315
|
+
let(:record) { ModelThatIsMultisearchable.new(multisearchable: false) }
|
275
316
|
|
276
317
|
it "should not create a PgSearch::Document record" do
|
277
318
|
expect { record.save! }.not_to change(PgSearch::Document, :count)
|
@@ -281,7 +322,7 @@ describe PgSearch::Multisearchable do
|
|
281
322
|
end
|
282
323
|
|
283
324
|
describe "after_update" do
|
284
|
-
let(:record) { ModelThatIsMultisearchable.create!(:
|
325
|
+
let(:record) { ModelThatIsMultisearchable.create!(multisearchable: true) }
|
285
326
|
|
286
327
|
context "when the document is present" do
|
287
328
|
before { expect(record.pg_search_document).to be_present }
|
@@ -356,7 +397,7 @@ describe PgSearch::Multisearchable do
|
|
356
397
|
end
|
357
398
|
|
358
399
|
describe "after_destroy" do
|
359
|
-
let(:record) { ModelThatIsMultisearchable.create!(:
|
400
|
+
let(:record) { ModelThatIsMultisearchable.create!(multisearchable: true) }
|
360
401
|
|
361
402
|
it "should remove its document" do
|
362
403
|
document = record.pg_search_document
|
@@ -375,7 +416,7 @@ describe PgSearch::Multisearchable do
|
|
375
416
|
|
376
417
|
model do
|
377
418
|
include PgSearch
|
378
|
-
multisearchable :
|
419
|
+
multisearchable unless: ->(record) { record.not_multisearchable? }
|
379
420
|
end
|
380
421
|
end
|
381
422
|
|
@@ -383,7 +424,7 @@ describe PgSearch::Multisearchable do
|
|
383
424
|
describe "after_create" do
|
384
425
|
describe "saving the record" do
|
385
426
|
context "when the condition is false" do
|
386
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
427
|
+
let(:record) { ModelThatIsMultisearchable.new(not_multisearchable: false) }
|
387
428
|
|
388
429
|
it "should create a PgSearch::Document record" do
|
389
430
|
expect { record.save! }.to change(PgSearch::Document, :count).by(1)
|
@@ -399,7 +440,7 @@ describe PgSearch::Multisearchable do
|
|
399
440
|
end
|
400
441
|
|
401
442
|
context "when the condition is true" do
|
402
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
443
|
+
let(:record) { ModelThatIsMultisearchable.new(not_multisearchable: true) }
|
403
444
|
|
404
445
|
it "should not create a PgSearch::Document record" do
|
405
446
|
expect { record.save! }.not_to change(PgSearch::Document, :count)
|
@@ -409,7 +450,7 @@ describe PgSearch::Multisearchable do
|
|
409
450
|
end
|
410
451
|
|
411
452
|
describe "after_update" do
|
412
|
-
let!(:record) { ModelThatIsMultisearchable.create!(:
|
453
|
+
let!(:record) { ModelThatIsMultisearchable.create!(not_multisearchable: false) }
|
413
454
|
|
414
455
|
context "when the document is present" do
|
415
456
|
before { expect(record.pg_search_document).to be_present }
|
@@ -504,7 +545,7 @@ describe PgSearch::Multisearchable do
|
|
504
545
|
|
505
546
|
model do
|
506
547
|
include PgSearch
|
507
|
-
multisearchable :
|
548
|
+
multisearchable if: :multisearchable?
|
508
549
|
end
|
509
550
|
end
|
510
551
|
|
@@ -512,7 +553,7 @@ describe PgSearch::Multisearchable do
|
|
512
553
|
describe "after_create" do
|
513
554
|
describe "saving the record" do
|
514
555
|
context "when the condition is true" do
|
515
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
556
|
+
let(:record) { ModelThatIsMultisearchable.new(multisearchable: true) }
|
516
557
|
|
517
558
|
it "should create a PgSearch::Document record" do
|
518
559
|
expect { record.save! }.to change(PgSearch::Document, :count).by(1)
|
@@ -528,7 +569,7 @@ describe PgSearch::Multisearchable do
|
|
528
569
|
end
|
529
570
|
|
530
571
|
context "when the condition is false" do
|
531
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
572
|
+
let(:record) { ModelThatIsMultisearchable.new(multisearchable: false) }
|
532
573
|
|
533
574
|
it "should not create a PgSearch::Document record" do
|
534
575
|
expect { record.save! }.not_to change(PgSearch::Document, :count)
|
@@ -538,7 +579,7 @@ describe PgSearch::Multisearchable do
|
|
538
579
|
end
|
539
580
|
|
540
581
|
describe "after_update" do
|
541
|
-
let!(:record) { ModelThatIsMultisearchable.create!(:
|
582
|
+
let!(:record) { ModelThatIsMultisearchable.create!(multisearchable: true) }
|
542
583
|
|
543
584
|
context "when the document is present" do
|
544
585
|
before { expect(record.pg_search_document).to be_present }
|
@@ -617,7 +658,7 @@ describe PgSearch::Multisearchable do
|
|
617
658
|
end
|
618
659
|
|
619
660
|
describe "after_destroy" do
|
620
|
-
let(:record) { ModelThatIsMultisearchable.create!(:
|
661
|
+
let(:record) { ModelThatIsMultisearchable.create!(multisearchable: true) }
|
621
662
|
|
622
663
|
it "should remove its document" do
|
623
664
|
document = record.pg_search_document
|
@@ -636,7 +677,7 @@ describe PgSearch::Multisearchable do
|
|
636
677
|
|
637
678
|
model do
|
638
679
|
include PgSearch
|
639
|
-
multisearchable :
|
680
|
+
multisearchable unless: :not_multisearchable?
|
640
681
|
end
|
641
682
|
end
|
642
683
|
|
@@ -644,7 +685,7 @@ describe PgSearch::Multisearchable do
|
|
644
685
|
describe "after_create" do
|
645
686
|
describe "saving the record" do
|
646
687
|
context "when the condition is true" do
|
647
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
688
|
+
let(:record) { ModelThatIsMultisearchable.new(not_multisearchable: true) }
|
648
689
|
|
649
690
|
it "should not create a PgSearch::Document record" do
|
650
691
|
expect { record.save! }.not_to change(PgSearch::Document, :count)
|
@@ -652,7 +693,7 @@ describe PgSearch::Multisearchable do
|
|
652
693
|
end
|
653
694
|
|
654
695
|
context "when the condition is false" do
|
655
|
-
let(:record) { ModelThatIsMultisearchable.new(:
|
696
|
+
let(:record) { ModelThatIsMultisearchable.new(not_multisearchable: false) }
|
656
697
|
|
657
698
|
it "should create a PgSearch::Document record" do
|
658
699
|
expect { record.save! }.to change(PgSearch::Document, :count).by(1)
|
@@ -670,7 +711,7 @@ describe PgSearch::Multisearchable do
|
|
670
711
|
end
|
671
712
|
|
672
713
|
describe "after_update" do
|
673
|
-
let!(:record) { ModelThatIsMultisearchable.create!(:
|
714
|
+
let!(:record) { ModelThatIsMultisearchable.create!(not_multisearchable: false) }
|
674
715
|
|
675
716
|
context "when the document is present" do
|
676
717
|
before { expect(record.pg_search_document).to be_present }
|
@@ -749,7 +790,7 @@ describe PgSearch::Multisearchable do
|
|
749
790
|
end
|
750
791
|
|
751
792
|
describe "after_destroy" do
|
752
|
-
let(:record) { ModelThatIsMultisearchable.create!(:
|
793
|
+
let(:record) { ModelThatIsMultisearchable.create!(not_multisearchable: false) }
|
753
794
|
|
754
795
|
it "should remove its document" do
|
755
796
|
document = record.pg_search_document
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe PgSearch::Normalizer do
|
@@ -5,7 +7,7 @@ describe PgSearch::Normalizer do
|
|
5
7
|
context "when config[:ignore] includes :accents" do
|
6
8
|
context "when passed an Arel node" do
|
7
9
|
it "wraps the expression in unaccent()" do
|
8
|
-
config = double("config", :
|
10
|
+
config = double("config", ignore: [:accents])
|
9
11
|
node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
|
10
12
|
|
11
13
|
normalizer = PgSearch::Normalizer.new(config)
|
@@ -17,7 +19,7 @@ describe PgSearch::Normalizer do
|
|
17
19
|
allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
|
18
20
|
node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
|
19
21
|
|
20
|
-
config = double("config", :
|
22
|
+
config = double("config", ignore: [:accents])
|
21
23
|
|
22
24
|
normalizer = PgSearch::Normalizer.new(config)
|
23
25
|
expect(normalizer.add_normalization(node)).to eq("my_unaccent(foo('bar'))")
|
@@ -27,7 +29,7 @@ describe PgSearch::Normalizer do
|
|
27
29
|
|
28
30
|
context "when passed a String" do
|
29
31
|
it "wraps the expression in unaccent()" do
|
30
|
-
config = double("config", :
|
32
|
+
config = double("config", ignore: [:accents])
|
31
33
|
|
32
34
|
normalizer = PgSearch::Normalizer.new(config)
|
33
35
|
expect(normalizer.add_normalization("foo")).to eq("unaccent(foo)")
|
@@ -37,7 +39,7 @@ describe PgSearch::Normalizer do
|
|
37
39
|
it "wraps the expression in that function" do
|
38
40
|
allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
|
39
41
|
|
40
|
-
config = double("config", :
|
42
|
+
config = double("config", ignore: [:accents])
|
41
43
|
|
42
44
|
normalizer = PgSearch::Normalizer.new(config)
|
43
45
|
expect(normalizer.add_normalization("foo")).to eq("my_unaccent(foo)")
|
@@ -48,7 +50,7 @@ describe PgSearch::Normalizer do
|
|
48
50
|
|
49
51
|
context "when config[:ignore] does not include :accents" do
|
50
52
|
it "passes the expression through" do
|
51
|
-
config = double("config", :
|
53
|
+
config = double("config", ignore: [])
|
52
54
|
|
53
55
|
normalizer = PgSearch::Normalizer.new(config)
|
54
56
|
expect(normalizer.add_normalization("foo")).to eq("foo")
|
data/spec/lib/pg_search_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
# For AR 5 and greater, the association reflection's cache needs be cleared
|
@@ -30,7 +32,7 @@ describe PgSearch do
|
|
30
32
|
end
|
31
33
|
|
32
34
|
context "with PgSearch.multisearch_options set to a Hash" do
|
33
|
-
before { allow(PgSearch).to receive(:multisearch_options).and_return(:
|
35
|
+
before { allow(PgSearch).to receive(:multisearch_options).and_return(using: :dmetaphone) }
|
34
36
|
subject do
|
35
37
|
PgSearch::Document.clear_searchable_cache
|
36
38
|
PgSearch.multisearch(query).map(&:searchable)
|
@@ -42,11 +44,11 @@ describe PgSearch do
|
|
42
44
|
end
|
43
45
|
model do
|
44
46
|
include PgSearch
|
45
|
-
multisearchable :
|
47
|
+
multisearchable against: :title
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
let!(:soundalike_record) { MultisearchableModel.create!(:
|
51
|
+
let!(:soundalike_record) { MultisearchableModel.create!(title: 'foning') }
|
50
52
|
let(:query) { "Phoning" }
|
51
53
|
it { is_expected.to include(soundalike_record) }
|
52
54
|
end
|
@@ -61,9 +63,9 @@ describe PgSearch do
|
|
61
63
|
allow(PgSearch).to receive(:multisearch_options) do
|
62
64
|
lambda do |query, soundalike|
|
63
65
|
if soundalike
|
64
|
-
{:
|
66
|
+
{ using: :dmetaphone, query: query }
|
65
67
|
else
|
66
|
-
{:query
|
68
|
+
{ query: query }
|
67
69
|
end
|
68
70
|
end
|
69
71
|
end
|
@@ -75,11 +77,11 @@ describe PgSearch do
|
|
75
77
|
end
|
76
78
|
model do
|
77
79
|
include PgSearch
|
78
|
-
multisearchable :
|
80
|
+
multisearchable against: :title
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
82
|
-
let!(:soundalike_record) { MultisearchableModel.create!(:
|
84
|
+
let!(:soundalike_record) { MultisearchableModel.create!(title: 'foning') }
|
83
85
|
let(:query) { "Phoning" }
|
84
86
|
|
85
87
|
context "with soundalike true" do
|
@@ -105,7 +107,7 @@ describe PgSearch do
|
|
105
107
|
before do
|
106
108
|
searchable_subclass_model = Class.new(SuperclassModel) do
|
107
109
|
include PgSearch
|
108
|
-
multisearchable :
|
110
|
+
multisearchable against: :content
|
109
111
|
end
|
110
112
|
stub_const("SearchableSubclassModel", searchable_subclass_model)
|
111
113
|
stub_const("AnotherSearchableSubclassModel", searchable_subclass_model)
|
@@ -113,13 +115,13 @@ describe PgSearch do
|
|
113
115
|
end
|
114
116
|
|
115
117
|
it "returns only results for that subclass" do
|
116
|
-
included = SearchableSubclassModel.create!(:
|
118
|
+
included = SearchableSubclassModel.create!(content: "foo bar")
|
117
119
|
|
118
|
-
SearchableSubclassModel.create!(:
|
119
|
-
SuperclassModel.create!(:
|
120
|
-
SuperclassModel.create!(:
|
121
|
-
NonSearchableSubclassModel.create!(:
|
122
|
-
NonSearchableSubclassModel.create!(:
|
120
|
+
SearchableSubclassModel.create!(content: "baz")
|
121
|
+
SuperclassModel.create!(content: "foo bar")
|
122
|
+
SuperclassModel.create!(content: "baz")
|
123
|
+
NonSearchableSubclassModel.create!(content: "foo bar")
|
124
|
+
NonSearchableSubclassModel.create!(content: "baz")
|
123
125
|
|
124
126
|
expect(SuperclassModel.count).to be 6
|
125
127
|
expect(SearchableSubclassModel.count).to be 2
|
@@ -132,7 +134,7 @@ describe PgSearch do
|
|
132
134
|
end
|
133
135
|
|
134
136
|
it "updates an existing STI model does not create a new pg_search document" do
|
135
|
-
model = SearchableSubclassModel.create!(:
|
137
|
+
model = SearchableSubclassModel.create!(content: "foo bar")
|
136
138
|
expect(SearchableSubclassModel.count).to eq(1)
|
137
139
|
# We fetch the model from the database again otherwise
|
138
140
|
# the pg_search_document from the cache is used.
|
@@ -144,12 +146,12 @@ describe PgSearch do
|
|
144
146
|
end
|
145
147
|
|
146
148
|
it "reindexing works" do
|
147
|
-
NonSearchableSubclassModel.create!(:
|
148
|
-
NonSearchableSubclassModel.create!(:
|
149
|
-
expected = SearchableSubclassModel.create!(:
|
150
|
-
SuperclassModel.create!(:
|
151
|
-
SuperclassModel.create!(:
|
152
|
-
SuperclassModel.create!(:
|
149
|
+
NonSearchableSubclassModel.create!(content: "foo bar")
|
150
|
+
NonSearchableSubclassModel.create!(content: "baz")
|
151
|
+
expected = SearchableSubclassModel.create!(content: "baz")
|
152
|
+
SuperclassModel.create!(content: "foo bar")
|
153
|
+
SuperclassModel.create!(content: "baz")
|
154
|
+
SuperclassModel.create!(content: "baz2")
|
153
155
|
|
154
156
|
expect(SuperclassModel.count).to be 6
|
155
157
|
expect(NonSearchableSubclassModel.count).to be 2
|
@@ -166,15 +168,15 @@ describe PgSearch do
|
|
166
168
|
end
|
167
169
|
|
168
170
|
it "reindexing searchable STI doesn't clobber other related STI models" do
|
169
|
-
SearchableSubclassModel.create!(:
|
170
|
-
AnotherSearchableSubclassModel.create!(:
|
171
|
+
SearchableSubclassModel.create!(content: "baz")
|
172
|
+
AnotherSearchableSubclassModel.create!(content: "baz")
|
171
173
|
|
172
174
|
expect(PgSearch::Document.count).to be 2
|
173
175
|
PgSearch::Multisearch.rebuild(SearchableSubclassModel)
|
174
176
|
expect(PgSearch::Document.count).to be 2
|
175
177
|
|
176
178
|
PgSearch::Document.clear_searchable_cache
|
177
|
-
classes = PgSearch::Document.all.collect {|d| d.searchable.class }
|
179
|
+
classes = PgSearch::Document.all.collect { |d| d.searchable.class }
|
178
180
|
expect(classes).to include SearchableSubclassModel
|
179
181
|
expect(classes).to include AnotherSearchableSubclassModel
|
180
182
|
end
|
@@ -195,7 +197,7 @@ describe PgSearch do
|
|
195
197
|
before do
|
196
198
|
searchable_subclass_model = Class.new(SuperclassModel) do
|
197
199
|
include PgSearch
|
198
|
-
multisearchable :
|
200
|
+
multisearchable against: :content
|
199
201
|
end
|
200
202
|
stub_const("SearchableSubclassModel", searchable_subclass_model)
|
201
203
|
stub_const("AnotherSearchableSubclassModel", searchable_subclass_model)
|
@@ -203,13 +205,13 @@ describe PgSearch do
|
|
203
205
|
end
|
204
206
|
|
205
207
|
it "returns only results for that subclass" do
|
206
|
-
included = SearchableSubclassModel.create!(:
|
208
|
+
included = SearchableSubclassModel.create!(content: "foo bar")
|
207
209
|
|
208
|
-
SearchableSubclassModel.create!(:
|
209
|
-
SuperclassModel.create!(:
|
210
|
-
SuperclassModel.create!(:
|
211
|
-
NonSearchableSubclassModel.create!(:
|
212
|
-
NonSearchableSubclassModel.create!(:
|
210
|
+
SearchableSubclassModel.create!(content: "baz")
|
211
|
+
SuperclassModel.create!(content: "foo bar")
|
212
|
+
SuperclassModel.create!(content: "baz")
|
213
|
+
NonSearchableSubclassModel.create!(content: "foo bar")
|
214
|
+
NonSearchableSubclassModel.create!(content: "baz")
|
213
215
|
|
214
216
|
expect(SuperclassModel.count).to be 6
|
215
217
|
expect(SearchableSubclassModel.count).to be 2
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'simplecov'
|
2
4
|
SimpleCov.start
|
3
5
|
|
@@ -20,7 +22,7 @@ require 'support/database'
|
|
20
22
|
require 'support/with_model'
|
21
23
|
|
22
24
|
DOCUMENTS_SCHEMA = lambda do |t|
|
23
|
-
t.belongs_to :searchable, :
|
25
|
+
t.belongs_to :searchable, polymorphic: true, index: true
|
24
26
|
t.text :content
|
25
27
|
t.timestamps null: false
|
26
28
|
end
|
data/spec/support/database.rb
CHANGED
@@ -1,27 +1,22 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
case RUBY_PLATFORM
|
4
|
+
when "java"
|
2
5
|
require "activerecord-jdbc-adapter"
|
3
|
-
|
6
|
+
ERROR_CLASS = ActiveRecord::JDBCError
|
4
7
|
else
|
5
8
|
require "pg"
|
6
|
-
|
9
|
+
ERROR_CLASS = PG::Error
|
7
10
|
end
|
8
11
|
|
9
|
-
error_classes << ActiveRecord::NoDatabaseError if defined? ActiveRecord::NoDatabaseError
|
10
|
-
|
11
12
|
begin
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
ActiveRecord::Base.establish_connection(:adapter => 'postgresql',
|
19
|
-
:database => 'pg_search_test',
|
20
|
-
:username => database_user,
|
21
|
-
:min_messages => 'warning')
|
13
|
+
ActiveRecord::Base.establish_connection(adapter: 'postgresql',
|
14
|
+
database: 'pg_search_test',
|
15
|
+
username: (ENV["TRAVIS"] ? "postgres" : ENV["USER"]),
|
16
|
+
min_messages: 'warning')
|
22
17
|
connection = ActiveRecord::Base.connection
|
23
18
|
connection.execute("SELECT 1")
|
24
|
-
rescue
|
19
|
+
rescue ERROR_CLASS, ActiveRecord::NoDatabaseError => e
|
25
20
|
at_exit do
|
26
21
|
puts "-" * 80
|
27
22
|
puts "Unable to connect to database. Please run:"
|
@@ -29,7 +24,7 @@ rescue *error_classes => exception
|
|
29
24
|
puts " createdb pg_search_test"
|
30
25
|
puts "-" * 80
|
31
26
|
end
|
32
|
-
raise
|
27
|
+
raise e
|
33
28
|
end
|
34
29
|
|
35
30
|
if ENV["LOGGER"]
|
@@ -41,19 +36,20 @@ def install_extension(name)
|
|
41
36
|
connection = ActiveRecord::Base.connection
|
42
37
|
extension = connection.execute "SELECT * FROM pg_catalog.pg_extension WHERE extname = '#{name}';"
|
43
38
|
return unless extension.none?
|
39
|
+
|
44
40
|
connection.execute "CREATE EXTENSION #{name};"
|
45
|
-
rescue StandardError =>
|
41
|
+
rescue StandardError => e
|
46
42
|
at_exit do
|
47
43
|
puts "-" * 80
|
48
44
|
puts "Please install the #{name} extension"
|
49
45
|
puts "-" * 80
|
50
46
|
end
|
51
|
-
raise
|
47
|
+
raise e
|
52
48
|
end
|
53
49
|
|
54
50
|
def install_extension_if_missing(name, query, expected_result)
|
55
51
|
result = ActiveRecord::Base.connection.select_value(query)
|
56
|
-
raise "Unexpected output for #{query}: #{result.inspect}" unless result.
|
52
|
+
raise "Unexpected output for #{query}: #{result.inspect}" unless result.casecmp(expected_result).zero?
|
57
53
|
rescue StandardError
|
58
54
|
install_extension(name)
|
59
55
|
end
|