Core Data: NSPredicate for many-to-many relationship. ("to-many key not allowed here")

Core DataIosNspredicate

Core 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOh Danny BoyView Question on Stackoverflow
Solution 1 - Core DataDave DeLongView Answer on Stackoverflow
Solution 2 - Core Datacaleb81389View Answer on Stackoverflow
Solution 3 - Core DataOleh HView Answer on Stackoverflow