RestKit Object Mapping relationships with foreign keys

core-data, restkit

Solution

I would make JobId a transient value in core data, and write a custom set and get for it.

The set would set the relationship to self.job=methodToReturnObjectMatchingJobId (this would be used by rest kit)

The get would return self.job.identifier

If you are not using mogenerator, I would suggest you have a look at it for all your core data needs.

Below is sample code of how i did it:

-(void) setClaimId:(NSNumber *)claimId{
     Claim *propertyClaim=[Claim listItemFromId:[claimId intValue] withContext:self.managedObjectContext]; 

    self.claim=propertyClaim; 
}
-(NSNumber*) claimId{

  return self.claim.referenceId;
}

where listItemFromId is a simple query that returns the object based on the id.

Problem

Can RestKit connect a relationship without storing the foreign key as an attribute, i.e., directly from the keypath in the JSON? In particular, I've got a Job has_many Rooms relationship. The room's JSON doesn't contain the job, rather, both are loaded separately: ``` - job: { id: 1, name: "John" } - room: { id: 4, job_id: 1, name: "spare bedroom" } ``` The Job is loaded before the Room. My CoreData models, Job has properties for ``` @interface Job : NSManagedObject @property (nonatomic, retain) NSNumber * identifier; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSSet *rooms; @end @interface Room : NSManagedObject @property (nonatomic, retain) NSNumber * identifier; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) Job *job; @end ``` Currently I add a `@property (nonatomic, strong) NSNumber *jobID;` to Room, which I `@synthesize`. ``` JobMapping: mapping = [RKManagedObjectMapping mappingForClass:[Job class]]; [mapping setPrimaryKeyAttribute:@"identifier"]; [mapping mapAttributes:@"name", nil]; [mapping mapKeyPath:@"id" toAttribute:@"identifier"]; [mapping mapRelationship:@"rooms" withMapping:[Room objectMapping]]; RoomMapping mapping = [RKManagedObjectMapping mappingForClass:[Room class]]; [mapping setPrimaryKeyAttribute:@"identifier"]; [mapping mapAttributes:@"name", nil]; [mapping mapKeyPath:@"id" toAttribute:@"identifier"]; [mapping mapKeyPath:@"job_id" toAttribute:@"jobID"]; [mapping mapRelationship:@"job" withMapping:[Job objectMapping]]; [mapping connectRelationship:@"job" withObjectForPrimaryKeyAttribute:@"jobID"]; ``` I was wondering if there's a way I can do this without the extra jobID property? I don't want to have a jobID attribute in the CoreData xcdatamodeld - it's redundant, as the relationship covers that. Also if I rebuild the NSManagedObjects, I need to re-add the jobID property, which is tedious. Can't I tell restkit to connect the Room to its corresponding Job via the job_id keypath in the JSON? If I remove the property, the `mapKeyPath:@"job_id"` line, and change the last line to `[mapping connectRelationship:@"job" withObjectForPrimaryKeyAttribute:@"job_id"];` I get ``` the entity Room is not key value coding-compliant for the key "job_id". ```

Original source