From the moment you start working with relationships, it becomes evident that Core Data is not a database. It is much more than that. Delete rules are a fine example of the framework's strength and flexibility. They are one of the conveniences that make working with Core Data enjoyable.
But what is a delete rule? And why is it important to know about delete rules when working with Core Data relationships? Let me show you with an example from Mastering Core Data With Swift.
Setting Up the Project
Create a new project in Xcode based on the Single View Application template. Name the project Notes and, to speed things up, check Use Core Data at the bottom.
Preparing the Data Model
Select Notes.xcdatamodeld, the data model of the project, to open the Data Model Editor. We are going to create two entities, Note and Category.
The Note entity has two attributes, title of type String and contents of type String. The Category entity has one attribute, name of type String.
Every note belongs to one category and a category can be linked to zero or more notes. This means we need to create a One-To-Many relationship between the Note and Category entities.
The Note entity defines a To-One relationship, category, with the Category entity as its destination. The Category entity defines a To-Many relationship, notes, with the Note category as its destination. This is what the data model should look like.
What happens if a note is deleted? Should the category the note belongs to also be deleted? No. But what happens if a category is deleted? Should it be possible to have notes without a category?
This brings us to delete rules. Every relationship has a delete rule. A delete rule defines what happens when the record that owns the relationship is deleted.
A delete rule defines what happens when the record that owns the relationship is deleted.
Select the notes relationship of the Category entity and open the Data Model Inspector on the right. By default, the delete rule of a relationship is set to nullify. Core Data supports four delete rules:
- No Action
No Action Delete Rule
If the delete rule of a relationship is set to No Action, nothing happens. Let me illustrate this with an example. We have a category that contains several notes. If the category is deleted, the notes are not notified of this event. The notes on the other end of the relationship believe that they are still associated with the deleted category.
I have never had a need to use this delete rule in a project. In most situations, you want to take some action when a record is deleted. And that is where the other delete rules come into play.
Nullify Delete Rule
If the delete rule of a relationship is set to Nullify, the destination of the relationship is nullified when the record is deleted.
For example, if a category has several notes and the category is deleted, the relationships pointing from the notes to the category are nullified. This is the default delete rule and the delete rule you will find yourself using most often.
Cascade Delete Rule
The Cascade delete rule is useful if the data model includes one or more dependencies. Let me give you an example. If a note should always have a category, the deletion of a category should automatically delete the notes associated with that category. In other words, the deletion of the category cascades or trickles down to the notes linked to the category. Even though this may make sense on paper, the user probably won't like it when you automatically delete its notes. The Deny delete rule is a better option in this scenario (see below).
If you are dealing with a Many-To-Many relationship, this is often not what you want. If a note can have several tags and a tag can be linked to several notes, deleting a tag should not result in the deletion of every note with that tag. The notes could be associated with other tags, for example.
Deny Delete Rule
Remember the previous example in which the deletion of a category resulted in the deletion of every note that belonged to that category. It may be better to apply the Deny delete rule.
Deny is another powerful and useful pattern. It is the opposite of the Cascade delete rule. Instead of cascading the deletion of a record, it prevents the deletion of the record.
For example, if a category is associated with several notes, the category can only be deleted if it is no longer tied to any notes. This configuration prevents the scenario in which notes are no longer associated with a category.
You cannot ignore delete rules when working Core Data. Take the time to understand the above concepts and leverage the power of Core Data. The default delete rule, Nullify, is often the correct choice. But don't make it hard on yourself by not exploring other options. Make Core Data work for you.
Delete rules are covered in detail in Mastering Core Data With Swift.