Reputation: 9082
What is the best practice for creating Unidirectional One to Many Relationships in Core Data?
For example...
Lets take two classic entity examples, "teacher" and "student".
Each student has one teacher, and each teacher has many students.
In CoreData right now you are forced to provide an inverse such that teacher is forced to have a reference to a 'student'. If you don't you get this nice warning that says something along the lines of...
file:///Users/josephastrahan/Documents/VisualStudioProjects/Swift3WorkOrders/WorkOrders/WorkOrders/WorkOrders.xcdatamodeld/WorkOrders.xcdatamodel/: warning: Misconfigured Property: Teacher.student should have an inverse
What if I don't want teacher to have a reference to student?
Some other posts have brought up that I should just allow the inverse anyways but I think this inverse may be causing an issue with one of my projects.
That said let me explain my exact issue.
Lets say that our teacher has a unique attribute int64 called 'id'. Lets say the students also have unique attribute int64 called 'id'.
The int64 is enforced to be unique by adding a constraint on the model for teacher on id. (refer to image below to see how that is done)
Every year there is new students but the teachers stay the same. So I decided that I want to delete all the students without deleting the reference to the teacher. So I set the delete rule to 'nullify' for the relationship for the teacher to student and 'nullify' for the student to teacher.
Now when I create a new student I want to assign one of the existing teachers to that student... (something like student.teacher = teacher object with id of 1 or the same id as before) however!! , because the teacher has the inverse relationship to a student that no longer exists (which in theory should be null) the program crashes!
I know this is the case as I've used print console logs to narrow it down the exact point that it occurs. Also I know this because if I add the delete rule of cascade for student the crash will go away but...then I lose my teacher! which I don't want...
Some things that I think might be the issue:
1.) When I do my testing I do it at the startup of the program which creates a new context everytime. Could it be that because I never deleted teacher it still thinks it refers to a student from a context that no longer exists? (if I'm even saying this right...)
I'm not sure the best solution to acheive what I'm trying to do with Coredata and any advice is much appreciated!
Note:
Forgot to mention I also have the Merge Policy of: NSMergeByPropertyObjectTrumpMergePolicy, which will overwrite the old data with the new. When I'm creating new students I'm creating new teachers also just using the same id which should follow this policy.
Upvotes: 3
Views: 1013
Reputation: 562
Unique Constraints are available with iOS9. Which have helped iOS Developers with adding and updating records in CoreData.
Unique Constraints make sure that records in an Entity are unique by the given fields. But unique constraints along with To-Many relationship leads to a lot of weird issues while resolving conflicts.
e.g. “Dangling reference to an invalid object.”
This post is basically focused to a small problem that may take days to fix.
http://muhammadzahidimran.com/2016/12/08/coredata-unique-constraints-and-to-many-relationship/
Upvotes: 0
Reputation: 80271
You are almost there.
Set<Student>
. Make sure the set is empty. NB:
If you want to keep the student in the database (for historical purposes) - it seems from your description that this is the case - you might also consider another scheme: give your students another attribute (such as a year) and use that to filter the student list. You would not have to delete or nullify anything. You could also do some more interesting time-based queries on the data.
Upvotes: 1