mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-05-07 12:45:15 +08:00
Enable support for mapping a relationship flexibly via assignment policies. You can now map a relationship and assign its value by setting, replacing, or unioning (combining) the relationship. closes #1073, closes #989
This commit is contained in:
@@ -444,10 +444,35 @@ NSArray *RKApplyNestingAttributeValueToMappings(NSString *attributeName, id valu
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applyReplaceAssignmentPolicyForRelationshipMapping:(RKRelationshipMapping *)relationshipMapping
|
||||
{
|
||||
if (relationshipMapping.assignmentPolicy == RKReplaceAssignmentPolicy) {
|
||||
if ([self.dataSource respondsToSelector:@selector(mappingOperation:deleteExistingValueOfRelationshipWithMapping:error:)]) {
|
||||
NSError *error = nil;
|
||||
BOOL success = [self.dataSource mappingOperation:self deleteExistingValueOfRelationshipWithMapping:relationshipMapping error:&error];
|
||||
if (! success) {
|
||||
RKLogError(@"Failed to delete existing value of relationship mapped with RKReplaceAssignmentPolicy: %@", error);
|
||||
self.error = error;
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
RKLogWarning(@"Requested mapping with `RKReplaceAssignmentPolicy` assignment policy, but the data source does not support it. Mapping has proceeded identically to the `RKSetAssignmentPolicy`.");
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)mapOneToOneRelationshipWithValue:(id)value mapping:(RKRelationshipMapping *)relationshipMapping
|
||||
{
|
||||
// One to one relationship
|
||||
RKLogDebug(@"Mapping one to one relationship value at keyPath '%@' to '%@'", relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath);
|
||||
|
||||
if (relationshipMapping.assignmentPolicy == RKUnionAssignmentPolicy) {
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Invalid assignment policy: cannot union a one-to-one relationship." };
|
||||
self.error = [NSError errorWithDomain:RKErrorDomain code:RKMappingErrorInvalidAssignmentPolicy userInfo:userInfo];
|
||||
return NO;
|
||||
}
|
||||
|
||||
id destinationObject = [self destinationObjectForMappingRepresentation:value withMapping:relationshipMapping.mapping];
|
||||
if (! destinationObject) {
|
||||
@@ -458,6 +483,10 @@ NSArray *RKApplyNestingAttributeValueToMappings(NSString *attributeName, id valu
|
||||
|
||||
// If the relationship has changed, set it
|
||||
if ([self shouldSetValue:&destinationObject atKeyPath:relationshipMapping.destinationKeyPath]) {
|
||||
if (! [self applyReplaceAssignmentPolicyForRelationshipMapping:relationshipMapping]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
RKLogTrace(@"Mapped relationship object from keyPath '%@' to '%@'. Value: %@", relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
|
||||
[self.destinationObject setValue:destinationObject forKey:relationshipMapping.destinationKeyPath];
|
||||
} else {
|
||||
@@ -500,6 +529,14 @@ NSArray *RKApplyNestingAttributeValueToMappings(NSString *attributeName, id valu
|
||||
RKLogWarning(@"WARNING: Detected a relationship mapping for a collection containing another collection. This is probably not what you want. Consider using a KVC collection operator (such as @unionOfArrays) to flatten your mappable collection.");
|
||||
RKLogWarning(@"Key path '%@' yielded collection containing another collection rather than a collection of objects: %@", relationshipMapping.sourceKeyPath, value);
|
||||
}
|
||||
|
||||
if (relationshipMapping.assignmentPolicy == RKUnionAssignmentPolicy) {
|
||||
RKLogDebug(@"Mapping relationship with union assignment policy: constructing combined relationship value.");
|
||||
id existingObjects = [self.destinationObject valueForKeyPath:relationshipMapping.destinationKeyPath];
|
||||
NSArray *existingObjectsArray = RKTransformedValueWithClass(existingObjects, [NSArray class], nil);
|
||||
[relationshipCollection addObjectsFromArray:existingObjectsArray];
|
||||
}
|
||||
|
||||
for (id nestedObject in value) {
|
||||
id mappableObject = [self destinationObjectForMappingRepresentation:nestedObject withMapping:relationshipMapping.mapping];
|
||||
if (! mappableObject) {
|
||||
@@ -520,6 +557,9 @@ NSArray *RKApplyNestingAttributeValueToMappings(NSString *attributeName, id valu
|
||||
|
||||
// If the relationship has changed, set it
|
||||
if ([self shouldSetValue:&valueForRelationship atKeyPath:relationshipMapping.destinationKeyPath]) {
|
||||
if (! [self applyReplaceAssignmentPolicyForRelationshipMapping:relationshipMapping]) {
|
||||
return NO;
|
||||
}
|
||||
if (! [self mapCoreDataToManyRelationshipValue:valueForRelationship withMapping:relationshipMapping]) {
|
||||
RKLogTrace(@"Mapped relationship object from keyPath '%@' to '%@'. Value: %@", relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, valueForRelationship);
|
||||
[self.destinationObject setValue:valueForRelationship forKeyPath:relationshipMapping.destinationKeyPath];
|
||||
|
||||
Reference in New Issue
Block a user