Bidirectional relational data in the panel

After quite a long pause on Kirby development I feel that I am stuck thinking in relational schemes for data storage again. My problem: I have two list of (sub)pages: groups and userss. They each hold a list of the other entity: A group has a list of users, and users have a list of groups.

A naive implementation is super simple, but requires me to update data in two places each time, so it is not practical.

My first idea to overcome this was to use hooks upon saving the page in order to update the referenced entities. However, I’m unsure how to handle deletions. Do I have a possibility to compare the old and new version of the page content in the hook?

A simpler solution would be to store all data on one side of the relation (e.g. each user has its groups, no additional list on the group side). When accessing a group page I would then iterate through all users (and obviously enable the cache). However, this leads to a different problem. Each time I update a user’s information, I have to invalidate all group caches. Is this possible?

I’m sure people here have build similar systems. How did you tackle this problem? Am I not thinking “the kirby way” and this actually super easy? Any pointers? :slight_smile:

I think it makes much more sense to only create one-way references.
You could store the list of users in the group pages, which results in less pages to iterate, but the other way around is probably more useful and easier to understand.

Each time any page is changed, the whole cache gets invalidated. So that shouldn’t be any problem.

I agree with @lukasbestle. I would also create one way relations rather than saving the information twice and save the group membership with the users.

I realise that it makes way more sense to store the data only once. The intention behind all those troubles was to make the site more intuitive for the user (of the panel; i.e. the administrator) by allowing him to edit the data wherever he wants to.

The entire cache? I didn’t know that. My best guess was that the panel would invalidate the cache of the page I was editing. What’s the reasoning behind deleting the entire cache? Enabling complex scenarios of sharing data between pages?

Exactly, change to a single file might in fact have effects on more than one page, so it would be difficult or impossible to find out which pages need to be removed from the cache.

I think it should be possible to build this using a combination of a custom field type (that fetches the data from the user pages to display them) and a hook to save the edits back to the user pages. The field itself shouldn’t store anything.

Added to what @texnixe said: A well-known example for this are menus. If you change one page title, basically the whole site changes, so that’s why the cache is cleared to prevent any strange behavior.

Interesting approach but I wonder how that works. Where do you store the data so that when the hook is triggered the content gets stored in the user pages?