Using Cascade Delete Rule and validateForDelete in a One-to-Many Relationship in iPhone Master Data

Introduction:

I have two objects defined as a one-to-many relationship: A <<-------> B. The relation of B to A is called myAs and is the to-many relation with Nullify as the Delete rule. The inverse relationship between A and B is a one-to-one relationship with Cascade, typically Delete.

I applied validateForDelete in class B like this:

- (BOOL)validateForDelete:(NSError **)error { [super validateForDelete:error]; BOOL validDelete = FALSE; if ([self.myAs count] == 0) { validDelete = TRUE; } return validDelete; } 

The purpose of this is to delete object B only if it has no more objects A (but always delete object B if it does not have any objects A). This validateForDelete works as intended if I check this check manually before saving: when deleting object B:

 if ([b validateForDelete:NULL]) { //delete b object... [context save:&error]; ... } 

The problem I am facing is that deleting object B is cascaded from deleting object A. Users will not have access to objects B directly - they are created and deleted through objects A. Therefore, my rule is that objects B must be deleted. when there are no more, the object associated with it must be forcibly applied to object A - therefore, the cascade when deleted.

The problem is that when I delete object A, validateForDelete is called on object B due to the cascade. I get a resolved error: Unresolved error (null), (null), because I do not call validateForDelete manually.

Question (s):

How can I access the validateForDelete call from cascading deletion programmatically so that I can pass the error variable and / or process the validateForDelete result from FALSE?

If the foregoing is not possible, how do I handle this use case? Is there an even more practical way to achieve this?

Thanks in advance.

+4
source share
2 answers

Firstly, your call to super ignores its response, and it does not act on the super response. This is usually a bad idea.

Secondly, when you say “NO” to validateForDelete, it throws an exception because the deletion rule cannot be completed; in this case, the cascade deletes. In short, the validation method is not the right place to handle this situation.

To deal with this situation, you must override the -prepareForDeletion method in class A and look at any Bs that matches this situation and delete them as necessary. You will also want to change the delete rule to collapse instead of the cascade. I would execute it as follows:

 - (void) prepareForDeletion { [super prepareForDeletion]; if (![self myB]) return; //I don't have a B if ([[[self myB] myAs] count] > 1) return; //Has more relationships [[self managedObjectContext] deleteObject:[self myB]]; } 

This will check if you have B, and if you do, if B has more than one relationship, and if not, add it to the delete queue. Otherwise, it will allow Core Data to simply terminate the relationship.

+12
source

You want to use the deny deletion rule. It was intended specifically for such situations.

0
source

Source: https://habr.com/ru/post/1302246/


All Articles