Setting Up a Parent-Child Relationship in Core Data

Setting up a parent-child relationship in Core Data

Soleil,

This is quite simple. First of of all, your model should look like the following (for the sake of simplicity I skipped attributes).

enter image description here

In this case a Tree can have zero or more Fruits (see fruits relationship). On the contrary, a Fruit has a tree relationship (an inverse relationship).

In particular, the fruits relationship should look like the following

enter image description here

Here, you can see that a to-many relationship has been set. The Delete rule means that if you remove a tree, also its fruits will be deleted.

The tree relationship is like the following

enter image description here

This is a one-to-one relationship since a fruit can exist only if attached to a tree. Optional flag is not set. So, when you create a fruit you also need to specify its parent (a tree in this case). Nullify rule means that when you delete a fruit, Core Data will not delete the tree associated with that fruit. It will delete only the fruit you specified.

When you create a Fruit entity you should follow a similar path

NSManagedObject *specificFruit = [NSEntityDescription insertNewObjectForEntityForName:@"Fruit" inManagedObjectContext:context];
[specificFruit setValue:parentTree forKey:@"tree"];

or if you have create NSManagedObject subclasses:

Fruit *specificFruit = [NSEntityDescription insertNewObjectForEntityForName:@"Fruit" inManagedObjectContext:context];
specificFruit.tree = parentTree;

Hope that helps.

P.S. Check the code since I've written without Xcode support.

Core Data with Swift - Parent/child relationship

Have you setup a relationship between the Workout and Lift entities in XCode. If each Workout will have only one Lift then use One-to-One, otherwise if each Workout has many Lifts then use One-to-Many.

Once the link is established you just tell the new Lift Entity (at the point when you create it) which Workout it should be connected to.

See this thread for more information:
Saving CoreData to-many relationships in Swift

Core data parent child relationship

You need to pass the parent's objectID to the second view controller (if I understood your setup correctly).

Fetch the parent (using existingObjectWithID:error: of the NSManagedObjectContext) in the other view context.

Set the child parent as the fetched object.

should look something like:

NSError* error = nil;
NSManagedObjectID* parentID = //the parent object id you selected
Parent* parent = [context existingObjectWithID:parentID error:&error];
if (parent) { //parent exists
Child *newChild = [NSEntityDescription insertNewObjectForEntityForName:@"Child"
inManagedObjectContext:context];
[newChild setValue:self.childName.text forKey:@"childName"];
[newChild setValue:self.born.text forKey:@"born"];
[newChild setValue:parent forKey:@"parent"];//Set the parent
} else {
NSLog(@"ERROR:: error fetching parent: %@",error);
}

Edit:

To get the selected object id (assuming you are using a NSFetchedReaultsController):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
//Use object.objectID as the selected object id to pass to the other view controller
//what ever you need to do with the object
}

How to create a core data model which parent entity and relationship

You most probably want something like this:
enter image description here

So the easiest way to achieve it is to control+drag from each entity to another in order to create the relationships (that way, XCode creates automatically the inverse relationship as well, so you save yourself one step). For the Item parent/children relationships just control+drag on itself. I hope that this makes sense...

PS. Although I don't fully understand why you need children on CategoryItem, since it's inherited by Item which already have such a relationship...

parent-child relationship inside an Entity

what is happening/why is it necessary/what is the purpose of setting up that relationship within the entity?

It isn't necessary, it's just an example and an easy way to create a hierarchy for a master-detail interface with a minimal Core Data model

assuming it's related, why might the author declare an NSManagedObject as a rootObject?

It's a simple way to create a 'master' object. Usually the 'master' or 'root' object would be defined by the only object in the context whose parent == nil.

None of the core data demos I've seen actually declare NSManagedObjects.

That doesn't really mean anything. Apps will often temporarily hold a pointer to a managed object instance. Indeed, a fetched request controller can hold multiple pointers to objects at any one time.

For example, the master/detail template in xCode just declares, which gives you a basic core data project

Apple examples aren't the best. That template also has the app delegate owning the Core Data stack and thats a terrible decision...

Aside:

The predicate can use the relationship better by using the relationship 'backwards'. i.e. rather than load the children relationship and check the contents it should reference the parent and check for equality:

@"parent == %@", selectedParent


Related Topics



Leave a reply



Submit