Skip to content

Commit 408072f

Browse files
committed
Add support and tests for inferring entity identifiers from superentity user info. closes RestKit#954
1 parent 0a28ecb commit 408072f

File tree

2 files changed

+57
-18
lines changed

2 files changed

+57
-18
lines changed

Code/CoreData/RKEntityMapping.m

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,27 @@
3636

3737
static NSArray *RKEntityIdentificationAttributesFromUserInfoOfEntity(NSEntityDescription *entity)
3838
{
39-
id userInfoValue = [[entity userInfo] valueForKey:RKEntityIdentificationAttributesUserInfoKey];
40-
if (userInfoValue) {
41-
NSArray *attributeNames = [userInfoValue isKindOfClass:[NSArray class]] ? userInfoValue : @[ userInfoValue ];
42-
NSMutableArray *attributes = [NSMutableArray arrayWithCapacity:[attributeNames count]];
43-
[attributeNames enumerateObjectsUsingBlock:^(NSString *attributeName, NSUInteger idx, BOOL *stop) {
44-
if (! [attributeName isKindOfClass:[NSString class]]) {
45-
[NSException raise:NSInvalidArgumentException format:@"Invalid value given in user info key '%@' of entity '%@': expected an `NSString` or `NSArray` of strings, instead got '%@' (%@)", RKEntityIdentificationAttributesUserInfoKey, [entity name], attributeName, [attributeName class]];
46-
}
47-
48-
NSAttributeDescription *attribute = [[entity attributesByName] valueForKey:attributeName];
49-
if (! attribute) {
50-
[NSException raise:NSInvalidArgumentException format:@"Invalid identifier attribute specified in user info key '%@' of entity '%@': no attribue was found with the name '%@'", RKEntityIdentificationAttributesUserInfoKey, [entity name], attributeName];
51-
}
52-
53-
[attributes addObject:attribute];
54-
}];
55-
return attributes;
56-
}
39+
do {
40+
id userInfoValue = [[entity userInfo] valueForKey:RKEntityIdentificationAttributesUserInfoKey];
41+
if (userInfoValue) {
42+
NSArray *attributeNames = [userInfoValue isKindOfClass:[NSArray class]] ? userInfoValue : @[ userInfoValue ];
43+
NSMutableArray *attributes = [NSMutableArray arrayWithCapacity:[attributeNames count]];
44+
[attributeNames enumerateObjectsUsingBlock:^(NSString *attributeName, NSUInteger idx, BOOL *stop) {
45+
if (! [attributeName isKindOfClass:[NSString class]]) {
46+
[NSException raise:NSInvalidArgumentException format:@"Invalid value given in user info key '%@' of entity '%@': expected an `NSString` or `NSArray` of strings, instead got '%@' (%@)", RKEntityIdentificationAttributesUserInfoKey, [entity name], attributeName, [attributeName class]];
47+
}
48+
49+
NSAttributeDescription *attribute = [[entity attributesByName] valueForKey:attributeName];
50+
if (! attribute) {
51+
[NSException raise:NSInvalidArgumentException format:@"Invalid identifier attribute specified in user info key '%@' of entity '%@': no attribue was found with the name '%@'", RKEntityIdentificationAttributesUserInfoKey, [entity name], attributeName];
52+
}
53+
54+
[attributes addObject:attribute];
55+
}];
56+
return attributes;
57+
}
58+
entity = [entity superentity];
59+
} while (entity);
5760

5861
return nil;
5962
}

Tests/Logic/CoreData/RKEntityMappingTest.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,40 @@ - (void)testInferenceOfSnakeCasedEntityNameWithAbbreviation
504504
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
505505
}
506506

507+
- (void)testEntityIdentifierInferenceSearchesParentEntities
508+
{
509+
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
510+
[entity setName:@"Monkey"];
511+
NSEntityDescription *parentEntity = [[NSEntityDescription alloc] init];
512+
[parentEntity setName:@"Parent"];
513+
[parentEntity setSubentities:@[ entity ]];
514+
NSAttributeDescription *identifierAttribute = [NSAttributeDescription new];
515+
[identifierAttribute setName:@"monkeyID"];
516+
[parentEntity setProperties:@[ identifierAttribute ]];
517+
NSArray *identificationAttributes = RKIdentificationAttributesInferredFromEntity(entity);
518+
expect(identificationAttributes).notTo.beNil();
519+
NSArray *attributeNames = @[ @"monkeyID" ];
520+
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
521+
}
522+
523+
- (void)testEntityIdentifierInferenceFromUserInfoSearchesParentEntities
524+
{
525+
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
526+
[entity setName:@"Monkey"];
527+
NSAttributeDescription *identifierAttribute = [NSAttributeDescription new];
528+
[identifierAttribute setName:@"monkeyID"]; // We ignore this by specifying the userInfo key
529+
NSAttributeDescription *nameAttribute = [NSAttributeDescription new];
530+
[nameAttribute setName:@"name"];
531+
[entity setProperties:@[ identifierAttribute, nameAttribute ]];
532+
[entity setUserInfo:@{ RKEntityIdentificationAttributesUserInfoKey: @"name" }];
533+
534+
NSEntityDescription *subentity = [NSEntityDescription new];
535+
[subentity setName:@"SubMonkey"];
536+
[entity setSubentities:@[ subentity ]];
537+
NSArray *identificationAttributes = RKIdentificationAttributesInferredFromEntity(subentity);
538+
expect(identificationAttributes).notTo.beNil();
539+
NSArray *attributeNames = @[ @"name" ];
540+
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
541+
}
542+
507543
@end

0 commit comments

Comments
 (0)