Core Data: NSPredicate for many-to-many relationship. ("to-many key not allowed here")
Core DataIosNspredicateCore Data Problem Overview
I have two entities named "Category" and "Article" which have a many to many relationship. I want to form a predicate which searches for all articles where category.name is equal to some value. I have the following:
NSEntityDescription *entityArticle = [NSEntityDescription entityForName:@"Article" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"categories.name == [cd] %@", category.name];
[request setSortDescriptors:sortDescriptors];
[request setEntity:entityArticle];
[request setPredicate:predicate];
NSMutableArray *results = [[managedObjectContext executeFetchRequest:request error:nil] mutableCopy];
if ([results count] > 0)
NSLog(@"Results found.");
else
NSLog(@"NO results found.");
[request release];
[sortDescriptor release];
[sortDescriptors release];
The error I receive is *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'
Are there any options to retrieve the desired data?
Core Data Solutions
Solution 1 - Core Data
You're trying to compare a collection (categories.name
) to a scalar value (category.name
). You need to either use a collection comparator (CONTAINS
), or use a predicate modifier (ANY
/ALL
/SOME
, etc).
Try using:
[NSPredicate predicateWithFormat:@"ANY categories.name =[cd] %@", category.name];
Or:
[NSPredicate predicateWithFormat:@"categories.name CONTAINS[cd] %@", category.name];
Solution 2 - Core Data
SWIFT SYNTAX
In case anyone happens upon this writing in swift as I did...
let predicate = NSPredicate(format: "ANY categories.name = %@", category.name!)
fetchRequest.predicate = predicate
worked for me.
Solution 3 - Core Data
For those who faced the same problem. You can use IN operator instead of = / == to look for specific objects in any Collection. Look here for reference. No difference Swift or Objective-C