Skip to content

Commit acfc603

Browse files
authored
feat: PPT-54 Add full text search capabilities to guest model (#278)
1 parent 4c40f28 commit acfc603

File tree

3 files changed

+92
-13
lines changed

3 files changed

+92
-13
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
-- +micrate Up
2+
-- SQL in section 'Up' is executed when this migration is applied
3+
4+
-- +micrate StatementBegin
5+
CREATE OR REPLACE FUNCTION tsv_search_tsvector_update() RETURNS TRIGGER LANGUAGE plpgsql AS $$
6+
BEGIN
7+
NEW.tsv_search := to_tsvector('simple',
8+
regexp_replace(
9+
COALESCE(NEW.email, '') || ' ' ||
10+
COALESCE(NEW.name, '') || ' ' ||
11+
COALESCE(NEW.preferred_name, '') || ' ' ||
12+
COALESCE(NEW.organisation, '') || ' ' ||
13+
COALESCE(NEW.phone, '') || ' ' ||
14+
COALESCE(NEW.id::TEXT, ''),
15+
'[@._]', ' ', 'g'
16+
) || ' ' ||
17+
COALESCE(NEW.email, '')
18+
);
19+
RETURN NEW;
20+
END $$;
21+
-- +micrate StatementEnd
22+
23+
ALTER TABLE guests ADD COLUMN tsv_search tsvector DEFAULT ''::tsvector;
24+
25+
CREATE INDEX idx_tsv_search ON guests USING gin(tsv_search);
26+
27+
UPDATE guests
28+
SET tsv_search = to_tsvector('simple',
29+
regexp_replace(
30+
COALESCE(email, '') || ' ' ||
31+
COALESCE(name, '') || ' ' ||
32+
COALESCE(preferred_name, '') || ' ' ||
33+
COALESCE(organisation, '') || ' ' ||
34+
COALESCE(phone, '') || ' ' ||
35+
COALESCE(id::TEXT, ''),
36+
'[@._]', ' ', 'g'
37+
) || ' ' ||
38+
COALESCE(email, '')
39+
);
40+
41+
CREATE TRIGGER tsv_search_trigger BEFORE INSERT OR UPDATE ON guests
42+
FOR EACH ROW EXECUTE FUNCTION tsv_search_tsvector_update();
43+
44+
-- +micrate Down
45+
-- SQL section 'Down' is executed when this migration is rolled back
46+
47+
DROP TRIGGER IF EXISTS tsv_search_trigger ON guests;
48+
DROP FUNCTION IF EXISTS tsv_search_tsvector_update();
49+
DROP INDEX IF EXISTS idx_tsv_search;
50+
ALTER TABLE guests DROP COLUMN IF EXISTS tsv_search;

spec/guest_spec.cr

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require "./helper"
2+
3+
module PlaceOS::Model
4+
describe Guest do
5+
Spec.after_each do
6+
Guest.clear
7+
end
8+
9+
it "can search via tsquery" do
10+
tenant = get_tenant
11+
Guest.create!(
12+
id: 1_i64,
13+
tenant_id: tenant.id,
14+
email: "john.doe@example.com",
15+
name: "John Doe",
16+
preferred_name: "Johnny",
17+
organisation: "Example Org",
18+
phone: "1234567890"
19+
)
20+
21+
Guest.create!(
22+
id: 2_i64,
23+
tenant_id: tenant.id,
24+
email: "jane.doe@example.com",
25+
name: "Jane Doe",
26+
organisation: "Another Org",
27+
phone: "0987654321"
28+
)
29+
30+
results = Guest.where("tsv_search @@ to_tsquery('simple', 'john & example')").all
31+
results.size.should eq 1
32+
results.first.id.should eq 1
33+
34+
results = Guest.where("tsv_search @@ to_tsquery('simple', 'jane')").all
35+
results.size.should eq 1
36+
results.first.id.should eq 2
37+
38+
results = Guest.where("tsv_search @@ to_tsquery('simple', 'example')").all
39+
results.size.should eq 2
40+
end
41+
end
42+
end

src/placeos-models/guest.cr

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ module PlaceOS::Model
3737
dependent: :destroy
3838
)
3939

40-
# Save searchable information
41-
before_save do
42-
@email = email.strip.downcase
43-
@searchable = String.build do |sb|
44-
sb << email
45-
sb << " #{name}" if name_assigned?
46-
sb << " #{preferred_name}" if preferred_name_assigned?
47-
sb << " #{organisation}" if organisation_assigned?
48-
sb << " #{phone}" if phone_assigned?
49-
sb << " #{id}" if id_assigned?
50-
end.downcase
51-
end
52-
5340
def change_extension_data(data : JSON::Any)
5441
@extension_data = data
5542
@extension_data_changed = true

0 commit comments

Comments
 (0)