Best approach to handle broken relations in Dexterity

Hi all,
In a Plone 5 site, where there are only Dexterity items and there isn't the reference_catalog anymore, what's the best approach to show/handle relations?

If we have a relation between two contents, and the "related" content is deleted, in the "relator" content remains a zombie relation until that content will be edited/saved.

I've found several examples in the documentation, Mastering Plone tutorial and the related items viewlet.
Both of them get the list of relations from the field/behavior and try to get the infos from each value.
Only in Mastering plone tutorial, there is a check for "isBroken" for every relation to avoid errors.

This check isn't made in the viewlet and it's a bug that i can fix soon, but before doing it i would like to know if the "isBroken" method is the official way to handle zombie relations in Dexterity or there are other ways. using an updated catalog (relation catalog) instead reading the values in the field/behavior?

Hi,

This is a known problem in plone.app.relationfield. I created an issue for it here (in 2014)

In archetypes days, when you delete content, p.a.relationfield (or actually one of the 'lower' packages in z3c.relationfield were listening in on events and cleaned up the incoming references on other object to X if object X was removed. This is broken and doesn't work anymore. See the ticket for more info, I figured it out half way back then but it got too complex for me.

Unless there have been fixes down in the meantime or other solutions, the default related items viewlet in plone 5 will break as well if you remove objects you relate to.

The 'fix' I'm doing in custom projects is filtering the relations using a list comprehension and isBroken:

def existing_new_articles(self):
    """ filter the relation list to only have relations to still existing
        content """
    articles = []
    if hasattr(self.context, 'new_articles'):
        articles = [a for a in self.context.new_articles
                    if not a.isBroken()]

The plone relation functionality needs a maintainer :frowning:

Would this be a good summer of code project?

Actually, I see a lot of relations that have an empty from_object, but still isBroken returns False, so that can't be relied upon.

What do these relations have as _from_id?
I had to monkey patch the RelationValues in plone.app.relationfield because of broken from_objects

Thanks for the replies..so there isn't a bulletproof solution as i understand..i need to double-check the relations to be secure.

For now it should work, but this feature really needs a lot of love from a maintainer like Patrick says :frowning:

Or a simplifying rewrite.

I could probably solve this problem you have, given more than half a day of work, which I don't have.

The foundation on which plone.app.relationfield sits, is pretty solid and relatively well documented, but it has a lot of features we do not need that add complexity that make it hard to understand.

For example, given how we use the relations, we probably don't really need a dedicated relation_catalog.
Then we would not need the IntId tool for relations, and this might mean, we can kick it out completely (not 100% sure).

With all this gone, relation code would be quite a bit simpler. Oh and the rewrite could maybe start handling permission handling and the related problems at the right level.

I hope this answers your question, @do3cc :

(Pdb) relation <z3c.relationfield.relation.RelationValue object at 0x7fc4fbca2b90> (Pdb) pp relation.__dict__ {'__parent__': <Document at community-preserves>, '_from_id': 1526966540, 'from_attribute': 'isReferencing', 'to_id': 252159100}

I guess isBroken code assumes, that you got the relation from an object and not the catalog.
Since from_object does not exist any more, you would have no way to receive a relation from the object itself.
That is not very nice, because afair one could still get the relation value by asking the to object for reverse references.
The relations code really is full of things that aren't thought out :frowning: I am still for rewriting as something simpler.