Search code examples
cocoa-touchcore-dataentity-relationship

Is it safe to manage relationships by fetching related objects within subclass of NSManagedObject


Say I have an employee entity and a company entity in core data.

So employee and company are related to each other like this:

Employee <<---> Company

Now I am trying to right a manageRelationships method in each class, something like this:

@interface Employee : NSManagedObject
- (void)manageRelationships;
@property (nonatomic, retain) Company *company; // for relationship
@property (nonatomic, retain) NSNumber *companyId; // acts as foreign key 
@end

@implementation Employee
@dynamic company;
@dynamic companyId;
- (void)manageRelationships
{
   // prepare a predicate as @"companyId == %@",self.companyId

   // execute a fetch request against Company entity

   // map relationship using self.company = retrievedCompanyObject
}

Now I have few questions:

  1. Is it safe to fire fetch request and map a relationship, as implemented above, within a subclass of NSManagedObject?

  2. Is their any better way to achieve it? (Idea behind above approach is- I will be calling above method on each created managed object so that it automatically manages and maps all associated relationships)

Please suggest.


Solution

  • I see what you are trying to do. But don't forget, Core Data provides you with an object graph, the database being only a secondary implementation detail. Thus, the whole notion of foreign keys is completely unnecessary, as the database layer is going to manage that for you.

    But alas, I assume you just do not have the Company object around when you create the employee but are just given the company id. Of course you can override the NSManagedObject subclass, maybe best in the setter of the id property:

    -(void)setCompanyId:(NSNumber*)newId {
       self.companyId = newId;
       if (!newId) { self.company = nil; }
       else {
          Company *myCompany = ... // fetch company
          self.company = myCompany;
       }
    }
    

    However, you can see how this is redundant. There is no need to keep the foreign key in your entity. You could retrieve it any time with

    NSNumber *companyId = employee.company.id;
    

    So maybe it is better to simply add a method to your Employee class that conveniently adds a company:

    -(void)addCompanyWithId:(NSNumber*)companyID {
       if (!companyID) { self.company = nil; }
       else {
          Company *employer = ...// fetch company
          self.company = employer ? employer : nil;
       }
    }