views:

74

answers:

1

I wonder if I've been doing too much myself, and could be relying on CoreData more. Suppose I have two managed objects, Dog and Tail, which have a one-to-one relationship. Dog has a relationship, tail, that is optional. Its inverse is owningDog. The delete rule from Dog to Tail is cascade. Tail's owningDog relationship is also optional. Its delete rule is nullify.

Both tail and owningDog are generated as retain properties by CoreData.

What do I need to do, minimally to accomplish the following?

  1. Move Dog A's Tail X to Dog B
  2. Delete Dog A (without deleting Dog B's new Tail X).

I've been doing something like this, written in full for clarity

-(void)graftThenKill
{
Tail* tempTail = A.tail;
A.tail = nil; // releases X, sets relationship to nil so we can delete without cascading
B.tail = tempTail; // retains X, sets Tail's owningDog to B
[moc deleteObject:A]; // now we have his tail, don't need A
}

Could I replace this with

-(void)graft
{
A.tail.owningDog = B; // Makes A's tail nil, safe to delete A without deleting X?
[moc deleteObject:A];
}
+2  A: 

Yes, -graft is sufficient. Core Data's true purpose in life is to maintain the object graph of a collection of object instances according to the description provided by a managed object model. If you declare a relationship as one-to-one, then assigning (in this case) A.tail.owningDog=B will reset the one-to-one relationship, breaking the previous relationships, if necessary. This is the reason to use inverse relationships in Core Data models, even if you don't think you'll need to traverse the relationship in both directions. The inverse relationship allows Core Data to help you by managing the entire relationship in the way I described above.

Barry Wark
Thanks, Barry! Oh, I need at least 15 characters in this comment. Thanks again then!
Jane Sales
You bet. Good luck!
Barry Wark