RestKit/RestKit — Issue #485: RootKeyPath ignored with nested JSON has-many relationship
Author: jdjennin
Created: 2011-12-27 22:32:56+00:00
State: open

I have some JSON that looks like this:

{"conversation":{"id":10,"event_id":67,"
conversation_messages":[

{"conversation_message":{"id":7,"conversation_id":10,"content":"This is a message","created_at":"2011-12-27T20:19:15Z"}},

{"conversation_message":{"id":8,"conversation_id":10,"content":"These dreams will go away. They all want you back to stay.","created_at":"2011-12-27T20:20:34Z"}}]}}

I have constructed the appropriate relationship mappings from Conversation to ConversationMessage. When setting up the ConversationMessage object mapping, it is done as follows:

RKObjectMapping *map = [RKObjectMapping mappingForClass:[self class]]; // self is ConversationMessage

[map mapKeyPath:@"content" toAttribute:@"content"];
[map mapKeyPath:@"created_at" toAttribute:@"createdAt"];
[map mapKeyPath:@"id" toAttribute:@"message_id"];

map.rootKeyPath = @"conversation_message";

This is returned from a method for use in the Conversation object's mapping:

RKObjectMapping *map = [RKObjectMapping mappingForClass:[self class]];

RKObjectRelationshipMapping *messageRelationship = [RKObjectRelationshipMapping mappingFromKeyPath:@"conversation_messages" toKeyPath:@"conversation_messages" withMapping:[ConversationMessage objectMapping]];
[map addRelationshipMapping:messageRelationship];

[map mapKeyPath:@"id" toAttribute:@"conversation_id"];
[map mapKeyPath:@"event_id" toAttribute:@"event_id"];
map.rootKeyPath = @"conversation";

This is returned from a method to the function which performs a GET with the RKObjectManager and RKObjectLoader objects.
This is constructed as follows:

RKObjectManager *man = [RKObjectManager sharedManager];
RKObjectMapping *conversationMap = [Conversation objectMapping];
[man loadObjectsAtResourcePath:[NSString stringWithFormat:@"/v1/events/%i/conversations.json", event.event_id.intValue] objectMapping:conversationMap delegate:self];

Here is the problem. The nested object mapping for ConversationMessage fails. It prints "WARNING: failed mapping nested object: (null)". The conversation_messages property of Conversation is populated with ConversationMessage objects, the properties of which are all nil. After spending hours trying to figure out the problem, I changed my definition of the object mapping of the ConversationMessage to this (which allows the operation to succeed):

RKObjectMapping *map = [RKObjectMapping mappingForClass:[self class]];

[map mapKeyPath:@"conversation_message.content" toAttribute:@"content"];
[map mapKeyPath:@"conversation_message.created_at" toAttribute:@"createdAt"];
[map mapKeyPath:@"conversation_message.id" toAttribute:@"message_id"];

map.rootKeyPath = @"conversation_message";

So it seems that the rootKeyPath attribute is ignored when there are nested objects in JSON.