Search code examples
iphoneobjective-ccocoa-touchcore-dataentity-relationship

CoreData Relationship Use


Im new with CoreData and have a relatively good hold on it, except now Im starting to look at relationships and need a little help.

An issue in my app made me think about it, I have two entities, TableInfo and PersonInfo.

A table can have many people sit at it, but a person can only sit at one table. So I know it would be a one to many relationship in that respect and it makes real world sense as well.

Anyway, in my app, I add a table to my person, so I basically say, this persons sits at this table. However, how do I handle, if I then go and delete the table I have already given to a person?

I figured relationships might come into play here, but I have never worked with them before so its tricky for me to understand where to go here.

If anyone knows of any good tutorials which will help with this issue or details core data relationships, or you can help I would very much appreciate it, thanks, or let me know if Im barking up the wrong tree with relationships for this issue.

Thanks!


Solution

  • This is a good situation where you would use Core Data relationships.

    The usual Apple Documentation (https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html) will give you a good grasp of how it works.

    In short, for a relationship you can specify a Delete Rule. In your case, you would probably choose "Nullify". That means, if you delete the table, the table-property of your Person will become null, indicating that your person no longer sits on a table.

    Edit: You could also specify "Cascade" which would delete the person together with the table (rather pointless, but slightly amusing thought). Or, you can specify "Deny", which will abort a deletion if at least one person still sits on the table.

    Example:

    Assume you have two entities, "TableInfo" and "PersonInfo". "PersonInfo" has a relationship called "table", "TableInfo" has a relationship called "persons". "table" is a to-one relationship with "TableInfo" as its target. "persons" is a to-many relationship with "PersonInfo" as its target.

    Now set the "Inverse Relationship" of "persons" to "table". The "Inverse Relationship" of "table" will bet set to "persons" automatically.

    If you let CoreData generate your model subclasses (you should!), you will end up with a class like this:

    @interface TableInfo : NSManagedObject
    
    @property (nonatomic, retain) NSSet *persons;
    @end
    
    @interface TableInfo (CoreDataGeneratedAccessors)
    
    - (void)addPersonsObject:(PersonInfo *)value;
    - (void)removePersonsObject:(PersonInfo *)value;
    - (void)addPersons:(NSSet *)values;
    - (void)removePersons:(NSSet *)values;
    

    As you can see, CoreData automatically creates appropiate accessors for you. Just use them.

    You can now do the following:

    TableInfo* myTable = [NSEntityDescription insertNewObjectForEntityForName:@"TableInfo" inManagedObjectContext:self.managedObjectContext];
    
    PersonInfo* myPerson = [NSEntityDescription insertNewObjectForEntityForName:@"PersonInfo" inManagedObjectContext:self.managedObjectContext];
    
    [myTable addPersonsObject:myPerson];
    NSLog(@"%@", myPerson.table); // will be your TableInfo object "myTable"
    

    In short, please read the documentation I linked above, there are plenty of examples there and on the internet. Feel free to ask questions on SO, but for "basic" needs the tutorials on the internet will be more complete and helpful.