manuelBetancurt
manuelBetancurt

Reputation: 16128

NSFetchRequest for all children of a parent

How do I fetch all child entities of a parent?

I have a table populated by a parent entity in Core Data. When the user touches a cell I intend to show another table with all children of that parent.

How does the NSFetchRequest look like for this please?

Edit:

model is like this:

student>>dates [one to many, one student have many days]

So I want all dates for any given student (selected by touching in student table cell for that student), then populate dates table with dates for that student.

Thanks!

Upvotes: 3

Views: 3017

Answers (4)

Lorenzo B
Lorenzo B

Reputation: 33428

Within your first table delegate, when you touch a specific cell, I'll inject the specific parent property to the second table controller. For example:

SecondController secondController = ... // alloc-init
secondController.studentToGrab = ...

where SecondController declaration has a studentToGrab property like the following:

@property (nonatomic, retain) Student* studentToGrab; // use strong with ARC, if non-ARC remember to release it

and in definition synthesize it.

Then in your second controller, within viewDidLoad method you could do:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourNameEntityForDate" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:20];

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"student == %@", studentToGrab];
[fetchRequest setPredicate:predicate];

// you can also use a sortdescriptors to order dates...

NSError *error = nil;
NSArray *resultArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error != nil) {

    NSLog(@"Error: %@", [error localizedDescription]);
    abort();
}

// use resultArray to populate something...

A remark when you deal with table you could also use NSFetchedResultController class. It has advantages when used for displaying data in tables.

Upvotes: 0

jrturton
jrturton

Reputation: 119242

You don't need a separate fetch request for this. All of the objects from the to-many relationship (don't call them child entities, that is misleading and incorrect) are available by accessing the relationship from the student object - something like student.dates. This gives you an NSSet, you can sort it and turn it to an array if you need to.

Upvotes: 1

Scott Corscadden
Scott Corscadden

Reputation: 2860

If you have custom classes, you could traverse the generated relationship (return [student dates]). That will get you an unordered NSSet on iOS4, or, you can do it with a fetch request (note I use ARC so no releases/autoreleases here):

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Date"
                                          inManagedObjectContext:moc];
[fetchRequest setEntity:entity];

NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:3];
[predicates addObject:[NSPredicate predicateWithFormat:@"student == %@", aStudent]];

// You might add other predicates
[fetchRequest setPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:predicates]];

// and if you want sorted results (why not, get the database to do it for you)
// sort by date to the top
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"dateAdded" ascending:NO]];
}
[fetchRequest setSortDescriptors:sortDescriptors];

NSError *error = nil;
NSArray *sorted = [moc executeFetchRequest:fetchRequest error:&error];
if (error) {
    // Handle the error, do something useful
}

return sorted;

Upvotes: 0

Costique
Costique

Reputation: 23722

Assuming that the entity and the class names are Student and Date, and the reverse relationship for Date->Student is called student,

Student *aStudent = ...;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity: [NSEntityDescription entityForName: @"Date" inManagedObjectContext: [aStudent managedObjectContext]]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"student == %@", aStudent]];

Upvotes: 2

Related Questions