mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 22:51:50 +08:00
Add support for skipping an aggregate relationship mapping in the event that the parent representation does not contain any values for the property mappings of the concrete RKObjectMapping configured for the relationship. fixes #1114, closes #1115
This commit is contained in:
@@ -198,6 +198,15 @@ static void RKSetValueForObject(id value, id destinationObject)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns YES if there is a value present for at least one key path in the given collection
|
||||
static BOOL RKObjectContainsValueForKeyPaths(id representation, NSArray *keyPaths)
|
||||
{
|
||||
for (NSString *keyPath in keyPaths) {
|
||||
if ([representation valueForKeyPath:keyPath]) return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@interface RKMappingOperation ()
|
||||
@property (nonatomic, strong, readwrite) RKMapping *mapping;
|
||||
@property (nonatomic, strong, readwrite) id sourceObject;
|
||||
@@ -599,8 +608,26 @@ static void RKSetValueForObject(id value, id destinationObject)
|
||||
for (RKRelationshipMapping *relationshipMapping in [self relationshipMappings]) {
|
||||
if ([self isCancelled]) return NO;
|
||||
|
||||
// The nil source keyPath indicates that we want to map directly from the parent representation
|
||||
id value = (relationshipMapping.sourceKeyPath == nil) ? self.sourceObject : [self.sourceObject valueForKeyPath:relationshipMapping.sourceKeyPath];
|
||||
id value = nil;
|
||||
if (relationshipMapping.sourceKeyPath) {
|
||||
value = [self.sourceObject valueForKeyPath:relationshipMapping.sourceKeyPath];
|
||||
} else {
|
||||
// The nil source keyPath indicates that we want to map directly from the parent representation
|
||||
value = self.sourceObject;
|
||||
RKObjectMapping *objectMapping = nil;
|
||||
|
||||
if ([relationshipMapping.mapping isKindOfClass:[RKObjectMapping class]]) {
|
||||
objectMapping = (RKObjectMapping *)relationshipMapping.mapping;
|
||||
} else if ([relationshipMapping.mapping isKindOfClass:[RKDynamicMapping class]]) {
|
||||
objectMapping = [(RKDynamicMapping *)relationshipMapping.mapping objectMappingForRepresentation:value];
|
||||
}
|
||||
|
||||
if (! objectMapping) continue; // Mapping declined
|
||||
NSArray *propertyKeyPaths = [relationshipMapping valueForKeyPath:@"mapping.propertyMappings.sourceKeyPath"];
|
||||
if (! RKObjectContainsValueForKeyPaths(value, propertyKeyPaths)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Track that we applied this mapping
|
||||
[mappingsApplied addObject:relationshipMapping];
|
||||
|
||||
@@ -2414,4 +2414,21 @@
|
||||
expect(user.coordinate.longitude).to.equal(200.5);
|
||||
}
|
||||
|
||||
- (void)testThatAggregatedRelationshipMappingsAreOnlyAppliedIfThereIsAtLeastOneValueInTheRepresentation
|
||||
{
|
||||
NSDictionary *objectRepresentation = @{ @"name": @"Blake" };
|
||||
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[RKTestUser class]];
|
||||
[userMapping addAttributeMappingsFromArray:@[ @"name" ]];
|
||||
RKObjectMapping *coordinateMapping = [RKObjectMapping mappingForClass:[RKTestCoordinate class]];
|
||||
[coordinateMapping addAttributeMappingsFromArray:@[ @"latitude", @"longitude" ]];
|
||||
[userMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"coordinate" withMapping:coordinateMapping]];
|
||||
RKTestUser *user = [RKTestUser new];
|
||||
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:objectRepresentation destinationObject:user mapping:userMapping];
|
||||
RKObjectMappingOperationDataSource *dataSource = [RKObjectMappingOperationDataSource new];
|
||||
mappingOperation.dataSource = dataSource;
|
||||
[mappingOperation start];
|
||||
expect(mappingOperation.error).to.beNil();
|
||||
expect(user.coordinate).to.beNil();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user