Add support for inferring attributes that match the snake-case _id pattern. closes #1047

This commit is contained in:
Blake Watters
2012-12-02 14:34:03 -05:00
parent cbb3f70571
commit a5dc037ef9
3 changed files with 58 additions and 7 deletions

View File

@@ -38,7 +38,7 @@
When `RKIdentificationAttributesInferredFromEntity` is invoked, the entity is first checked for a user info key specifying the identifying attributes. If the user info of the given entity contains a value for the key 'RKEntityIdentificationAttributes', then that value is used to construct an array of attributes. The user info key must contain a string or an array of strings specifying the names of attributes that exist in the given entity.
If no attributes are specified in the user info, then the entity is searched for an attribute whose name matches the llama-cased name of the entity. For example, an entity named 'Article' would have an inferred identifier attribute of 'articleID' and an entity named 'ApprovedComment' would be inferred as 'approvedCommentID'. If such an attribute is found within the entity, an array is returned containing the attribute. If none is returned, the the attributes are searched for the following names:
If no attributes are specified in the user info, then the entity is searched for an attribute whose name matches the llama-cased or snake-cased name of the entity. For example, an entity named 'Article' would have an inferred identifying attributes of 'articleID' and 'article_id', and an entity named 'ApprovedComment' would be inferred as 'approvedCommentID' and 'approved_comment_id'. If such an attribute is found within the entity, an array is returned containing the attribute. If none is returned, the the attributes are searched for the following names:
1. 'identifier'
1. 'id'

View File

@@ -58,12 +58,26 @@ static NSArray *RKEntityIdentificationAttributesFromUserInfoOfEntity(NSEntityDes
return nil;
}
// Given 'Human', returns 'humanID'; Given 'AmenityReview' returns 'amenityReviewID'
static NSString *RKEntityIdentificationAttributeNameForEntity(NSEntityDescription *entity)
static NSString *RKUnderscoredStringFromCamelCasedString(NSString *camelCasedString)
{
NSError *error = nil;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:@"((^[a-z]+)|([A-Z]{1}[a-z]+)|([A-Z]+(?=([A-Z][a-z])|($))))" options:0 error:&error];
if (! regularExpression) return nil;
NSMutableArray *lowercasedComponents = [NSMutableArray array];
[regularExpression enumerateMatchesInString:camelCasedString options:0 range:NSMakeRange(0, [camelCasedString length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
[lowercasedComponents addObject:[[camelCasedString substringWithRange:[result range]] lowercaseString]];
}];
return [lowercasedComponents componentsJoinedByString:@"_"];
}
// Given 'Human', returns 'humanID' and 'human_id'; Given 'AmenityReview' returns 'amenityReviewID' and 'amenity_review_id'
static NSArray *RKEntityIdentificationAttributeNamesForEntity(NSEntityDescription *entity)
{
NSString *entityName = [entity name];
NSString *lowerCasedFirstCharacter = [[entityName substringToIndex:1] lowercaseString];
return [NSString stringWithFormat:@"%@%@ID", lowerCasedFirstCharacter, [entityName substringFromIndex:1]];
NSString *camelizedIDAttributeName = [NSString stringWithFormat:@"%@%@ID", lowerCasedFirstCharacter, [entityName substringFromIndex:1]];
NSString *underscoredIDAttributeName = [NSString stringWithFormat:@"%@_id", RKUnderscoredStringFromCamelCasedString([entity name])];
return @[ camelizedIDAttributeName, underscoredIDAttributeName ];
}
static NSArray *RKEntityIdentificationAttributeNames()
@@ -97,7 +111,7 @@ NSArray *RKIdentificationAttributesInferredFromEntity(NSEntityDescription *entit
return RKArrayOfAttributesForEntityFromAttributesOrNames(entity, attributes);
}
NSMutableArray *identifyingAttributes = [NSMutableArray arrayWithObject:RKEntityIdentificationAttributeNameForEntity(entity)];
NSMutableArray *identifyingAttributes = [RKEntityIdentificationAttributeNamesForEntity(entity) mutableCopy];
[identifyingAttributes addObjectsFromArray:RKEntityIdentificationAttributeNames()];
for (NSString *attributeName in identifyingAttributes) {
NSAttributeDescription *attribute = [entity attributesByName][attributeName];

View File

@@ -322,8 +322,6 @@
#pragma mark - Entity Identifier Inference
// TODO: The attributes to auto-detect: entityNameID, ID, identififer, url, URL
- (void)testEntityIdentifierInferenceForEntityWithLlamaCasedIDAttribute
{
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
@@ -467,4 +465,43 @@
}
}
- (void)testInferenceOfSnakeCasedEntityName
{
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
[entity setName:@"Monkey"];
NSAttributeDescription *identifierAttribute = [NSAttributeDescription new];
[identifierAttribute setName:@"monkey_id"];
[entity setProperties:@[ identifierAttribute ]];
NSArray *identificationAttributes = RKIdentificationAttributesInferredFromEntity(entity);
expect(identificationAttributes).notTo.beNil();
NSArray *attributeNames = @[ @"monkey_id" ];
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
}
- (void)testInferenceOfCompoundSnakeCasedEntityName
{
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
[entity setName:@"ArcticMonkey"];
NSAttributeDescription *identifierAttribute = [NSAttributeDescription new];
[identifierAttribute setName:@"arctic_monkey_id"];
[entity setProperties:@[ identifierAttribute ]];
NSArray *identificationAttributes = RKIdentificationAttributesInferredFromEntity(entity);
expect(identificationAttributes).notTo.beNil();
NSArray *attributeNames = @[ @"arctic_monkey_id" ];
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
}
- (void)testInferenceOfSnakeCasedEntityNameWithAbbreviation
{
NSEntityDescription *entity = [[NSEntityDescription alloc] init];
[entity setName:@"ArcticMonkeyURL"];
NSAttributeDescription *identifierAttribute = [NSAttributeDescription new];
[identifierAttribute setName:@"arctic_monkey_url_id"];
[entity setProperties:@[ identifierAttribute ]];
NSArray *identificationAttributes = RKIdentificationAttributesInferredFromEntity(entity);
expect(identificationAttributes).notTo.beNil();
NSArray *attributeNames = @[ @"arctic_monkey_url_id" ];
expect([identificationAttributes valueForKey:@"name"]).to.equal(attributeNames);
}
@end