I have the following two entities in my Core Data Model:
Manufacture {name, ...other attributes}
Product {name, .... other attributes}
I have setup a One to Many Relationship:
Manufacturer.manufactures <------>> Product.manufacturedBy
I am trying to build a predicate to return all Products belonging to Manufacturers that match a search string. E.g. if there are two Manufacturers, "King Nut", and "Queen Nut" then a search on "Nut" should return all products made by both King Nut and Queen Nut.
My predicate works perfectly when my filter is on the Product entity, however I cannot get any predicate to work when filtering on the Manufacturer entity. The result set is empty.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Product" inManagedObjectContext:[GBKDB context]];
searchValue = @"nut";
NSString *wildcardString = [NSString stringWithFormat:@"*%@*", searchValue];
I have tried the following:
predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchValue];
predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name like %@",wildcardString];
predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name matches %@",wildcardString];
predicate = [NSPredicate predicateWithFormat:@"ALL manufacturedBy.name like %@",wildcardString];
predicate = [NSPredicate predicateWithFormat:@"ALL manufacturedBy.name like[cd] %@",@wildcardString];
To get Product
s manufactured by a manufacturer with name containing "nut", your request should look like:
NSString* searchVal = @"nut";
NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Product"];
[r setPredicate:[NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchVal]];
To get Manufacturer
s with product names containing "nut" your request should look like:
NSString* searchVal = @"nut";
NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Manufacture"];
[r setPredicate:[NSPredicate predicateWithFormat:@"ANY manufactures.name CONTAINS[cd] %@",searchVal]];
If your result set is empty, it might be due to the fact that no objects answer the predicate (contain the substring "nut").
Try adding some fake entities with known names and testing.
Edit:
This is the code you could use for testing:
typedef void(^config_block_t)(id);
- (void) synthesizeObjectsOfEntity:(NSString*)entity
context:(NSManagedObjectContext*)context
count:(NSUInteger)count
configBlock:(config_block_t)configBlock
{
for (;count;--count) {
NSManagedObject* object = [NSEntityDescription insertNewObjectForEntityForName:entity
inManagedObjectContext:context];
configBlock(object);
}
}
- (void) synthesizeProductsAndManufacturersInContext:(NSManagedObjectContext*)context
{
NSMutableArray* manufacturers = [NSMutableArray new];
[self synthesizeObjectsOfEntity:@"Manufactur"
context:context
count:10
configBlock:^(Manufactur* m) {
m.name = [NSString stringWithFormat:@"m-%u%u%u",arc4random()%10,arc4random()%10,arc4random()%10];
[manufacturers addObject:m];
}];
[self synthesizeObjectsOfEntity:@"Product"
context:context
count:100
configBlock:^(Product* p) {
p.name = [NSString stringWithFormat:@"p-%u%u%u",arc4random()%10,arc4random()%10,arc4random()%10];
p.manufacturedBy = manufacturers[arc4random() % [manufacturers count]];
}];
[context save:NULL];
[context reset];
NSString* searchVal = @"3";
NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Product"];
[r setPredicate:[NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchVal]];
NSArray* match = [context executeFetchRequest:r error:NULL];
NSLog(@"matched: %u",[match count]);
}