How to create an NSFetchRequest which filters Core Data objects based on attributes AND relationships?

36,554

You can traverse relationships in an NSPredicate. For example, you could write something like

[NSPredicate predicateWithFormat:@"title == %@ AND blockbuster.name LIKE \"Blockbuster C\"", @"Transformers 2"]

Now, if you don't have a property to compare against and you need to check actual objects, then you could use something like

[NSPredicate predicateWithFormat:@"title == %@ AND blockbuster IN %@", @"Transformers 2", setOfBlockbusters]

The full syntax is documented here. But setOfBlockbusters could be a set, an array, or a dictionary (if it's a dictionary, the values, not the keys, are used).

Share:
36,554
Dave
Author by

Dave

Updated on July 18, 2022

Comments

  • Dave
    Dave almost 2 years

    I have a Core Data model setup like so:

    • Blockbuster Entity
      • To-Many relationship to DVD entities.
    • DVD Entity
      • title attribute (string)
      • To-One relationship to a parent Blockbuster entity

    A single Blockbuster can have multiple DVD's inside of it (To-Many). Each DVD can only be part of a single Blockbuster (To-One).

    There are multiple Blockbuster's, and some may contain DVD entities which share the same title as DVD entities from other Blockbuster's. For example, Blockbuster A might have a copy of "Transformers 2", and so does Blockbuster C and Blockbuster G. Let's pretend no Blockbuster has more than one copy of the same titled movie.

    I'm interested in grabbing the Transformers 2 DVD from Blockbuster C. I don't want the copies from Blockbuster A or G, because my boss frequents there, and I can only get away with burning this piece of garbage in Blockbuster C.


    My question is, how do I form an NSFetchRequest which grabs a DVD with the title "Transformers 2", which is a child of the Blockbuster "C" parent entity?

    This type of request will grab all the "Transformer 2" DVD's, but not the one specific to the Blockbuster C entity:

    NSManagedObjectContext *moc = [self managedObjectContext];
    
    NSString *aTitle = @"Transformers 2";
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title == %@", aTitle];
    [request setEntity:[NSEntityDescription entityForName:@"DVD" inManagedObjectContext:moc]];
    [request setPredicate:predicate];
    
    NSError *error = nil;
    NSArray *results = [moc executeFetchRequest:request error:&error];
    
    // error handling code
    [request release];
    

    Is there a way to pass, say, the Object ID of a related object inside the NSPredicate, filtering based on that?