views:

83

answers:

2

Hi all. I have a Core Data store which contains a number of MediaItem entities that describe, well, media items. I also have NewsItems, which have one-to-many relationships to a number of MediaItems. So far so good.

However, I also have PlayerItems and GalleryItems which also have one-to-many relationships to MediaItems. So MediaItems are shared across entities.

Given that many entities may have one-to-many relationships, how can I set up reciprocal relationships from a MediaItem to all (1 or more) of the entities which have relationships to it and, furthermore, how can I implement rules to delete MediaItems when the number of those reciprocal relationships drops to 0?


For the record (and in case it comes in useful to somebody else), I solved this by creating an abstract MediaLinkedEntity class with a one-to-many relationship to MediaItems (named MediaItems at the MediaLinkedEntity end and LinkedEntities at the MediaItem end). I then subclassed this entity for NewsItems and GalleryItems and implemented the following -prepareForDeletion method in MediaLinkedEntity:

- (void)prepareForDeletion {

    NSSet *mediaItems = self.MediaItems;
    NSSet *linkedEntities;

    // step through all media items we link to
    for( MediaItem *mediaItem in mediaItems ){
        linkedEntities = mediaItem.LinkedEntities;
        if( [ linkedEntities count ] == 1 && [ linkedEntities containsObject: self ] ){
        // if this MediaLinkedEntity is the only entry in the mediaItem's linked entities list, delete it.
            [ mediaItem.managedObjectContext deleteObject: mediaItem ];
        }
    }   

    [ super prepareForDeletion ];
}

Essentially, following Marcus's answer below.

A: 

However, I also have PlayerItems and GalleryItems which also have one-to-many relationships to MediaItems. So MediaItems are shared across entities.

The easiest but not so beautiful way would be to create inverse relationships for each of the MediaItem relations.

Another possibility would be to create an abstract parent entity with a relation to MediaItem and inherit GalleryItem, NewsItems, PlayerItem from this general entity.

Given that many entities may have one-to-many relationships, how can I set up reciprocal relationships from a MediaItem to all (1 or more) of the entities which have relationships to it and, furthermore, how can I implement rules to delete MediaItems when the number of those reciprocal relationships drops to 0?

There are several ways to create this behaviour. You could use KVO to observe all the inverse relations of MediaItem

Martin Brugger
+1  A: 

The best answer for this is to have an abstract parent entity that handles the relationship in a generic way. This will allow you to reduce the number of relationships in your model.

As for the delete rule, you should create a subclass for "one" side of the relationships and implement their -prepareForDeletion method to check for orphaned items on the many side and then delete them when it occurs.

Marcus S. Zarra
That's brilliant, thanks Marcus.
Henry Cooke