Since it might not be an cache issue, it might just be an issue of orphaned collections or FK constraints. Directus magically creates join tables and foreign key constraints when adding relational interfaces, but cleaning those up might require additional steps.
I was too lazy to write a removal guide on my own, so I asked ChatGPT to do it for me. It basically looks good to me, but let me know if you encounter any failures.
Even if that doesn’t solve this problem, it may serve others as reference. It may help you tho, identifying orphan collections, based on the naming convention Directus uses when creating join tables.
Additional remark: The “Relational Trigger” you mentioned, just affects how referential integrity is handled on the join table rows while the relation is in effect. It doesn’t delete the join table or alter join table rows when dropping the interface.
Removing Relationships in Directus (Data Modeling Phase)
If you’re still designing your schema in Directus Data Studio and decide to remove relationships — such as many-to-many, many-to-any, one-to-many, or many-to-one — it’s important to follow the correct deletion order:
Always delete relationship fields first, then delete any join collections.
To illustrate each type, we’ll consistently use the following collections:
countries
cities
mountains
countries_cities (M2M join collection)
countries_points_of_interest (M2A polymorphic join collection)
Many-to-Many (M2M): countries ↔ cities (via countries_cities)
Structure
countries and cities are linked by a many-to-many relationship.
- Directus automatically creates a join collection:
countries_cities.
Removal Steps
- Go to the
countries collection.
- Delete the relationship field pointing to
cities.
- Go to
cities.
- Delete the inverse relationship field pointing to
countries, if added.
- Go to the
countries_cities collection.
- Delete the collection itself.
M2M is fully removed.
Many-to-Any (M2A): countries, cities, mountains → countries_points_of_interest
Structure
- Each of the collections (
countries, cities, mountains) uses a many-to-any field called points_of_interest.
- The field is originally created in
countries, so Directus names the join collection: countries_points_of_interest.
This is useful when multiple resource types (like countries, cities, and mountains) can reference shared items (e.g., tourist attractions).
Removal Steps
- Go to the
countries collection.
- Delete the
points_of_interest field.
- Go to the
cities collection.
- Delete the
points_of_interest field, if added.
- Go to the
mountains collection.
- Delete the
points_of_interest field, if added.
- Go to the
countries_points_of_interest collection.
- Delete the collection.
M2A and its polymorphic join table are fully removed.
One-to-Many (O2M): countries → cities
Structure
- Each city belongs to one country.
cities has a foreign key field (e.g., country_id).
countries may have a virtual field (e.g., cities) to show the related records.
Removal Steps
- Go to the
cities collection.
- Delete the foreign key field (
country_id).
- Go to the
countries collection.
- Delete the virtual field (
cities), if present.
O2M is now fully removed.
Many-to-One (M2O): cities → countries
Structure
- Each city references a single country — the inverse of the O2M relationship.
cities has a field like country_id.
countries may show related cities in a virtual field.
Removal Steps
- Go to the
cities collection.
- Delete the
country_id field.
- Go to the
countries collection.
- Delete the virtual field (
cities), if present.
M2O is also removed — same structure as O2M but viewed from the reverse direction.
Summary Table
| Relationship Type |
Example |
Step 1: Delete Fields |
Step 2: Delete Collection |
| Many-to-Many |
countries ↔ cities |
Relationship fields in countries and cities |
countries_cities |
| Many-to-Any |
countries, cities, mountains → shared |
points_of_interest fields in all three collections |
countries_points_of_interest |
| One-to-Many |
countries → cities |
country_id in cities, cities virtual field in countries |
(no join collection) |
| Many-to-One |
cities → countries |
country_id in cities, cities virtual field in countries |
(no join collection) |