mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-06-19 18:24:12 +08:00
* Implemented relation mapping in RKDynamicRouter
* Added specs covering the functionality
This commit is contained in:
@@ -100,8 +100,72 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
// By default return a form encoded serializable dictionary
|
||||
return [object propertiesForSerialization];
|
||||
// set up dictionary containers
|
||||
NSDictionary* elementsAndProperties = [object propertiesForSerialization];
|
||||
NSDictionary* relationships = [object relationshipsForSerialization];
|
||||
int propertyCount = [elementsAndProperties count];
|
||||
int relationshipCount = [relationships count];
|
||||
int entryCount = propertyCount + relationshipCount;
|
||||
NSMutableDictionary* resourceParams = [NSMutableDictionary dictionaryWithCapacity:entryCount];
|
||||
|
||||
// add elements and properties
|
||||
for (NSString* elementName in [elementsAndProperties allKeys]) {
|
||||
id value = [elementsAndProperties valueForKey:elementName];
|
||||
NSString* attributeName = [elementName stringByReplacingOccurrencesOfString:@"-" withString:@"_"];
|
||||
if (![attributeName isEqualToString:@"id"]) {
|
||||
NSString* keyName = [NSString stringWithFormat:@"%@", attributeName];
|
||||
[resourceParams setValue:value forKey:keyName];
|
||||
}
|
||||
}
|
||||
|
||||
void (^handlePrimaryKey)(Class, NSMutableDictionary *, id) = ^(Class blockClass, NSMutableDictionary *attributes, id object) {
|
||||
if ([blockClass respondsToSelector:@selector(primaryKeyProperty)]) {
|
||||
NSString *primaryKey = [blockClass performSelector:@selector(primaryKeyProperty)];
|
||||
id primaryKeyValue = [object valueForKey:primaryKey];
|
||||
NSString* primaryKeyValueString = [NSString stringWithFormat:@"%@", primaryKeyValue];
|
||||
|
||||
// Primary key value isn't defined
|
||||
if (primaryKeyValue == nil || [primaryKeyValueString isEqualToString:@"0"]) {
|
||||
// Exclude id
|
||||
[attributes removeObjectForKey:@"id"];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// add nested relationships
|
||||
for (NSString* elementName in [relationships allKeys]) {
|
||||
NSObject *relationship = [relationships objectForKey:elementName];
|
||||
NSString *relationshipPath = [NSString stringWithFormat:@"%@", elementName];
|
||||
// to-many relation
|
||||
if ([relationship isKindOfClass:[NSArray class]] ||
|
||||
[relationship isKindOfClass:[NSSet class]]) {
|
||||
NSMutableArray *children = [NSMutableArray array];
|
||||
for (id child in (NSEnumerator *)relationship) {
|
||||
Class class = [child class];
|
||||
NSMutableDictionary* childAttributes = [RKObjectMappableGetPropertiesByElement(child) mutableCopy];
|
||||
|
||||
handlePrimaryKey(class, childAttributes, child);
|
||||
|
||||
[children addObject:[NSDictionary dictionaryWithDictionary:childAttributes]];
|
||||
}
|
||||
|
||||
[resourceParams setValue:children
|
||||
forKey:relationshipPath];
|
||||
// to-one relation
|
||||
} else {
|
||||
Class class = [relationship class];
|
||||
NSMutableDictionary* childAttributes = [RKObjectMappableGetPropertiesByElement(relationship) mutableCopy];
|
||||
|
||||
handlePrimaryKey(class, childAttributes, relationship);
|
||||
|
||||
[resourceParams setValue:childAttributes
|
||||
forKey:relationshipPath];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return resourceParams;
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -41,4 +41,14 @@
|
||||
return @"railsID";
|
||||
}
|
||||
|
||||
+ (NSDictionary*)elementToRelationshipMappings {
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"human", @"human",
|
||||
nil];
|
||||
}
|
||||
|
||||
+ (NSArray*)relationshipsToSerialize {
|
||||
return [NSArray arrayWithObject:@"human"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "RKSpecEnvironment.h"
|
||||
#import "RKManagedObjectStore.h"
|
||||
#import "RKHuman.h"
|
||||
#import "RKCat.h"
|
||||
|
||||
@interface RKDynamicRouterSpec : NSObject <UISpec> {
|
||||
}
|
||||
@@ -110,4 +111,106 @@
|
||||
[expectThat(resourcePath) should:be(@"/this/is/the/path")];
|
||||
}
|
||||
|
||||
- (void)itShouldSerializeToOneRelationWithoutId
|
||||
{
|
||||
RKDynamicRouter* router = [[[RKDynamicRouter alloc] init] autorelease];
|
||||
|
||||
RKHuman* human = [[RKHuman object] autorelease];
|
||||
RKCat* cat = [[RKCat object] autorelease];
|
||||
|
||||
cat.name = @"Cat";
|
||||
human.name = @"Owner";
|
||||
cat.human = human;
|
||||
|
||||
NSDictionary* serialization = (NSDictionary*) [router serializationForObject:cat method:RKRequestMethodPOST];
|
||||
NSDictionary* serializedRelation = [serialization objectForKey:@"human"];
|
||||
[expectThat([serializedRelation objectForKey:@"name"]) should:be(@"Owner")];
|
||||
}
|
||||
|
||||
- (void)itShouldSerializeToOneRelationWithId
|
||||
{
|
||||
RKDynamicRouter* router = [[[RKDynamicRouter alloc] init] autorelease];
|
||||
|
||||
RKHuman* human = [[RKHuman object] autorelease];
|
||||
RKCat* cat = [[RKCat object] autorelease];
|
||||
|
||||
cat.name = @"Cat";
|
||||
human.railsID = [NSNumber numberWithInt:1];
|
||||
human.name = @"Owner";
|
||||
cat.human = human;
|
||||
|
||||
NSDictionary* serialization = (NSDictionary*) [router serializationForObject:cat method:RKRequestMethodPOST];
|
||||
NSDictionary* serializedRelation = [serialization objectForKey:@"human"];
|
||||
[expectThat([serializedRelation objectForKey:@"name"]) should:be(@"Owner")];
|
||||
}
|
||||
|
||||
|
||||
- (void)itShouldSerializeToManyRelationWithoutId
|
||||
{
|
||||
RKDynamicRouter* router = [[[RKDynamicRouter alloc] init] autorelease];
|
||||
|
||||
RKHuman* human = [[RKHuman object] autorelease];
|
||||
human.name = @"Owner";
|
||||
RKCat* cat1 = [[RKCat object] autorelease];
|
||||
cat1.name = @"Cat1";
|
||||
[human addCatsObject:cat1];
|
||||
RKCat* cat2 = [[RKCat object] autorelease];
|
||||
cat2.name = @"Cat2";
|
||||
[human addCatsObject:cat2];
|
||||
|
||||
NSDictionary* serialization = (NSDictionary*) [router serializationForObject:human method:RKRequestMethodPOST];
|
||||
NSArray* serializedCats = [serialization objectForKey:@"cats"];
|
||||
|
||||
NSDictionary *serCat1 = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:0], @"age",
|
||||
[NSNumber numberWithInt:0], @"birth_year",
|
||||
@"Cat1", @"name",
|
||||
nil];
|
||||
|
||||
NSDictionary *serCat2 = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:0], @"age",
|
||||
[NSNumber numberWithInt:0], @"birth_year",
|
||||
@"Cat2", @"name",
|
||||
nil];
|
||||
[expectThat([serializedCats count]) should:be(2)];
|
||||
[expectThat([serializedCats containsObject:serCat1]) should:be(TRUE)];
|
||||
[expectThat([serializedCats containsObject:serCat2]) should:be(TRUE)];
|
||||
}
|
||||
|
||||
- (void)itShouldSerializeToManyRelationWithId
|
||||
{
|
||||
RKDynamicRouter* router = [[[RKDynamicRouter alloc] init] autorelease];
|
||||
|
||||
RKHuman* human = [[RKHuman object] autorelease];
|
||||
human.name = @"Owner";
|
||||
RKCat* cat1 = [[RKCat object] autorelease];
|
||||
cat1.name = @"Cat1";
|
||||
cat1.railsID = [NSNumber numberWithInt:1];
|
||||
[human addCatsObject:cat1];
|
||||
RKCat* cat2 = [[RKCat object] autorelease];
|
||||
cat2.name = @"Cat2";
|
||||
cat2.railsID = [NSNumber numberWithInt:2];
|
||||
[human addCatsObject:cat2];
|
||||
|
||||
NSDictionary* serialization = (NSDictionary*) [router serializationForObject:human method:RKRequestMethodPOST];
|
||||
NSArray* serializedCats = [serialization objectForKey:@"cats"];
|
||||
|
||||
NSDictionary *serCat1 = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:0], @"age",
|
||||
[NSNumber numberWithInt:0], @"birth_year",
|
||||
[NSNumber numberWithInt:1], @"id",
|
||||
@"Cat1", @"name",
|
||||
nil];
|
||||
|
||||
NSDictionary *serCat2 = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:0], @"age",
|
||||
[NSNumber numberWithInt:0], @"birth_year",
|
||||
[NSNumber numberWithInt:2], @"id",
|
||||
@"Cat2", @"name",
|
||||
nil];
|
||||
[expectThat([serializedCats count]) should:be(2)];
|
||||
[expectThat([serializedCats containsObject:serCat1]) should:be(TRUE)];
|
||||
[expectThat([serializedCats containsObject:serCat2]) should:be(TRUE)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user