Question

I need help with a fetch request that filters children where children and parent have a many to many relationship. all the examples I've found are for one to many relationships.

Playlists can contain many songs via songs relationship Song can be in many playlists via playlists relationship. These relationships are inverses of each other.

enter image description here

I am trying to find a filtered list of Song objects where playlist id = 1 and song name begins with "a".

I've tried many things, don't want to include code for all of them, but they included trying subqueries, getting the playlist then trying to run a nsprediate on it's songs nsset (converted to nsarray), and a few other things.

Here's what I think is closest to what I need.

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.playlistRKCoreDataManager.managedObjectStore.mainQueueManagedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSString *queryStr = [NSString stringWithFormat:@"playlists.playlist_id == \"%@\" AND name BEGINSWITH[c] \"%@\"", playlistID, songQuery];
[request setPredicate:[NSPredicate predicateWithFormat: queryStr]];
[request setEntity:entityDescription];
Was it helpful?

Solution

You should not use stringWithFormat to build a predicate. This will fail if the search strings (playlistID, songQuery) contains special characters, in particular if they contain a quote ".

A much better and safer method is

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY playlists.playlist_id =[cd] %@ AND name BEGINSWITH[c] %@", playlistID, songQuery];
[request setPredicate:predicate];

because predicateWithFormat handles all these cases correctly.

(It is mainly the same reason why one should use "prepared statements" for SQL queries, even if this: http://xkcd.com/327/ would probably not happen with Core Data :-)

OTHER TIPS

of course, after hours of trying to figure this out, I find my own answers minutes after posting this question.

NSString *queryStr = [NSString stringWithFormat:@"ANY playlists.playlist_id =[cd] \"%@\" AND name BEGINSWITH[c] \"%@\"", playlistID, songQuery];
[request setPredicate:[NSPredicate predicateWithFormat: queryStr]];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top