Both sides have many
An order has many dishes; a dish appears in many orders. Neither table can hold a single foreign key. The solution is a third, junction table with one row per pair — like order_items(order_id, dish_id, qty).
A junction table
CREATE TABLE tags (
id serial PRIMARY KEY,
name text NOT NULL UNIQUE
);
CREATE TABLE dish_tags (
dish_id int NOT NULL REFERENCES dishes(id) ON DELETE CASCADE,
tag_id int NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (dish_id, tag_id)
);
INSERT INTO tags (name) VALUES ('spicy'), ('gluten-free'), ('popular');
INSERT INTO dish_tags VALUES (1, 3), (3, 1), (3, 3), (5, 2);
SELECT d.name, string_agg(t.name, ', ' ORDER BY t.name) AS tags
FROM dishes d
JOIN dish_tags dt ON dt.dish_id = d.id
JOIN tags t ON t.id = dt.tag_id
GROUP BY d.name;