I have the following trigger function that updates the object's tsvector
column when its details change:
CREATE OR REPLACE FUNCTION customer_search_trigger() RETURNS trigger AS $$
BEGIN
NEW.customers_search_vector :=
setweight(to_tsvector('english', CONCAT(NEW.first_name, ' ', NEW.last_name)), 'A') ||
setweight(to_tsvector('english', NEW.email), 'A') ||
setweight(to_tsvector('english', coalesce(NEW.physical_address,'')), 'D');
RETURN NEW;
END;
$$ LANGUAGE plpgsql
Customer records are associated with Project records, via the customer_id
column on the projects
table. The projects
table also has a tsvector
column, named projects_search_vector
, and that column contains tsvectors for not just the project details, but also the project's customer:
CREATE OR REPLACE FUNCTION project_search_trigger() RETURNS trigger AS $$
DECLARE
customer record;
BEGIN
SELECT first_name, last_name, email, physical_address INTO customer FROM customers_customers WHERE id = NEW.customer_id;
NEW.projects_search_vector :=
setweight(to_tsvector('english', coalesce(NEW.name,'')), 'A') ||
setweight(to_tsvector('english', coalesce(NEW.description,'')), 'B') ||
setweight(to_tsvector('english', CONCAT(customer.first_name, ' ', customer.last_name)), 'D') ||
setweight(to_tsvector('english', customer.email), 'D') ||
setweight(to_tsvector('english', coalesce(customer.physical_address,'')), 'D');
RETURN NEW;
END;
$$ LANGUAGE plpgsql
This way, when the user searches for "Bob Green", any projects that belong to Bob Green (the customer) are also returned.
QUESTION: I now want to make it so that when a customer's details change, the associated projects' tsvector
columns are also updated. In other words, if the customer's last name changes from "Green" to "Brown", then when the user searches for "Brown" I want their projects to still get returned in the results.
How can I do this?
Best Answer
Make an after-update trigger on "customer" which does a dummy update on "project", which will then fire the trigger on project to do its thing: