12

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".
Zeophlite
  • 1,607
  • 3
  • 19
  • 36
  • Did you find out how to properly connect relationship in Core Data without having a redundant ID property next to the real relationship? – thejaz May 24 '13 at 14:24

1 Answers1

5

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.

Will Johnston
  • 864
  • 4
  • 18
  • Doesn't this make the relationship mapping of Restkit redundant? Should I disable Restkit's mapping, or perhaps leave setClaimId blank? – geon Mar 08 '13 at 10:54
  • What I am doing is using the mapping or claimId and using that to set the relationship to claim object outside of restKit. So you would not have a mapping in restKit for the relationship in this case (if this is how you are doing it). – Will Johnston Mar 10 '13 at 13:25