1

From what I have been reading, for a relationship like department <->> employee, I can't set a simple deletion rule that will cause department to be deleted if the last employee in a department is deleted. Instead, I have to code this rule.

I thought I might use key-value observing, with the didChangeValueForKey: method of the department entity. I want to centralize this delete action into one place, in a DRY way.

I wouldn't expect that the department entity could delete itself, like this:

- (void) didChangeValueForKey:key {
    if (![key isEqualToString @"employee") return;
    if (self.employee == NULL)
        [self deleteAndSave];  // a category method
}

So I might post a notification, instead

- (void) didChangeValueForKey:key {
    if (![key isEqualToString @"employee") return;
    if (self.employee == NULL)
        [[NSNotificationCenter defaultCenter] postNotificationName:@"empDelete" object:self];
}

and then have the deletion take place in an object where I handle things like my managed object context.

Am I missing something that would make this easier?

Jim
  • 5,940
  • 9
  • 44
  • 91

2 Answers2

1

A good place for deletion rules is -(void)prepareForDeletion. You can implement any behavior you need, from the most simplistic to the most sophisticated.

When deleting a department, you could per example move all the department's employees to the parent department, if any. And when you delete an employee, you can check if the parent department still have employees and delete it if left empty. Your call.

  • I thought about using `-(void)prepareForDeletion` but this looked like it would create a problem, due to my delete rule from department to employee being cascade. Deleting the department entity here would delete the employee entity by the cascade rule. then my explicit delete would reference the employee entity that was just deleted. I haven't tried it, but this looks like it would create a problem, nd probably an error. I really want a method that is called after the employee is deleted, I think. Am I missing something? – Jim Jun 27 '12 at 20:12
  • It's fine to reference a deleted managed object. The object in memory will be released when no more strong reference exists. In fact, it will be released after the database row's been deleted in all cases. isDeleted doesn't work in all cases. In addition, you may want to check if the object still have a context and an objectID. Also, prepareForDeletion is called when the object is about to be deleted from the store, not when you call `[context deleteObject:]`. The object is likely to have been marked as deleted a while ago. – fabrice truillot de chambrier Jun 27 '12 at 20:41
  • Okay, I'll give it a try tonight. From the documentation, it looks like I don't need to call [super prepareForDeletion]. Do you know anything about this that I should know? – Jim Jun 27 '12 at 20:48
  • `prepareForDeletion` default implementation does nothing. If you use a hierarchy of entities, you may or may not call on super, depending on the entities behaviors. This is very specific to each application I think. – fabrice truillot de chambrier Jun 27 '12 at 21:02
0

Your solution seems fine, and here are some other probable ways of doing it. Core Data Deletion rules and many-to-many relationships

Community
  • 1
  • 1
Nikita Pestrov
  • 5,876
  • 4
  • 31
  • 66