Core Data model of video and entities I have a Core Data model with two entities: Video and Playlist.


A Video can be a member of many Playlists
A Playlist can have many Videos, including the same Video multiple times
A Playlist's Videos are ordered



  Video &lt;&lt;----->> Playlist


That being said, I've decided that I need a third entity: Playlist Item.


A Playlist Item has an index
A Playlist Item can only have a relationship with one Video entity and one Playlist entity


And so, this causes the original specification to be revised...


A Video can have many Playlist Items
A Playlist can have many Playlist Items, but each Playlist Item has a unique index
A Playlist's Playlist Items are ordered using the index attribute


Video &lt;----&gt;&gt; Playlist Item &lt;&lt;----&gt; Playlist

So, the addition of the Playlist Item entity allows me to have many-to-many relationships between Video and Playlist and still maintain ordered lists. Adding this third entity however adds complexity to the overall design.

I am wondering if it is wise to hide that complexity managing the Playlist Item objects in the Video and Playlist implementations.

Video

@interface Video : NSManagedObject

@property (strong, nonatomic) NSSet *playlists; // Custom accessor; Transient attribute; data persisted in Playlist Item
// No declared NSSet for playlistItems

@end


Playlist

@interface Playlist: NSManagedObject

@property (nonatomic, strong) NSArray *videos; // Custom accessor...
// No declared playlistItems here either!

@end


It seems by doing this I will gain code that is better at revealing intentions.

The code smell I'm getting is that NSManagedObjects subclasses are model classes and should therefore not have any controller type glue. Furthermore it makes my Video and Playlist classes completely dependent upon the Playlist Items class. But, all of that said writing the accessor is trivial, which is why I'm considering this approach:

- (NSArray *)videos
{    
    [self willAccessValueForKey:@"videos"];
    NSArray *v = [self primitiveVideos];
    [self didAccessValueForKey:@"videos"];

    if (v) {
        return v;
    }

    NSSet *pi = [self playlistItems];

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES];
    NSArray *orderedPlaylistItems = [pi sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

    NSUInteger count = [orderedPlaylistItems count];
    NSMutableArray *videos = [NSMutableArray arrayWithCapacity:count];
    for (int index = 0; index &lt; count; index++) {
        [videos addObject:[[orderedPlaylistItems objectAtIndex:index] video]];
    }

    v = videos;
    [self setPrimitiveVideos:v];

    return v;
}


(This code is pretty rough, but you get the point, a few lines and voila! an array of video objects from the set of playlist items)

Maybe there is a design pattern or best practice that would help guide my decision?
Perhaps I'm missing something, but it seems that the Video objects don't really need to know about what playlists they belong to, do they?

A playlist is a collection of videos.  You don't need a playlist index object.  You just need an array on each playlist that keeps track of what videos are on its playlist and in what order.  A simple array does all this for you.

It seems to me that the only reason a video would need to know what playlists it belonged to is if you wanted to provide some functionality for a video to quickly find all playlists it belonged to.  And when I say this, I mean a request where it's important for this information to be returned near instantly.

Even without the video knowing any information about the playlists, your code could still iterate through every playlist asking it whether or not it contained a given video and get the answer to what all playlists the video belongs to.  This might be a little time consuming, but I think it's a rare request.

But it seems what's most likely is that a user will either want to play an individual video, or play a playlist.  The request to play all playlists that contain this particular video seems an odd one to me.