Joel H.
Joel H.

Reputation: 2784

Restkit Mapping - Use Embedded Object/Relationship As Identification Attribute

I'm having trouble mapping a particular JSON structure, as illustrated in a simplified form here:

{"personDetails":{"eyeColor":"brown",
                  "height":"2m 12cm",
                  "specialRestrictions":null,
                  "person":{"personId":42,
                            "firstName":"Hummingbird",
                            "lastName":"Collins",
                            "dob":1360856245000,
                            "gender":"F",
                            "personCode":"8DECCC6D-68CA-47E1-AV7F-84C2039D517",
                            "isAdmin":false}
                  }
}

In this case, I'd like to use the "personId" field, or even the "person" object itself, as a primary key of my "personDetails" object. As far as I can tell, there is no way to do this. I looked into RKConnectionDescription, but it doesn't seem applicable in this case, since the entire object is embedded, not just a foreign key attribute.

I basically want the relationship to be one-to-one, in that, when I call my service, like this,

http://server/services/getPersonDetailsByID/42

the details can map and persist in CoreData, overwriting the PersonDetails for that Person that were previously saved. At the moment, multiple PersonDetails objects can exist for the same Person locally, because there is no key in place.

So, my question is this: can RestKit mapping be set up to accomplish this intended behavior? Or will I need to handle the deletion of any outdated CoreData objects myself?

Edit: Here's how my mapping looks currently.

RKEntityMapping* personDetailsMapping = [RKEntityMapping mappingForEntityForName:
          @"personDetails" inManagedObjectStore:objectManager.managedObjectStore];
[personDetailsMapping addAttributeMappingsFromArray:@[@"eyeColor", @"height",  
                                                         @"specialRestrictions"]];
[personDetailsMapping addPropertyMapping:[RKRelationshipMapping
          relationshipMappingFromKeyPath:@"person" toKeyPath:@"person" 
                     withMapping:personMapping]]; // personMapping defined earlier

Here are two different ways I've tried adding an Identification attribute:

personDetailsMapping.identificationAttributes = @[@"person"];

and

personDetailsMapping.identificationAttributes = @[@"personId"];

at different times, and they each throw an error like this:

Invalid attribute 'personId': no attribute was found for the given name in the 'PersonDetails' entity.

Upvotes: 0

Views: 1303

Answers (1)

Wain
Wain

Reputation: 119031

It's possible that adding the key path as the identification attribute will work. I haven't actually tried it but key paths work in most places.

personDetailsMapping.identificationAttributes = @[ @"person.personId" ]

If it doesn't, you can setup your mapping to copy the person id into the details object. You will need to add a new persistent attribute and then you use the key path in the mapping:

@"personId" : @"person.personId"

Upvotes: 1

Related Questions