diff --git a/Code/CoreData/RKConnectionDescription.h b/Code/CoreData/RKConnectionDescription.h index fb580dbb..52959e3a 100644 --- a/Code/CoreData/RKConnectionDescription.h +++ b/Code/CoreData/RKConnectionDescription.h @@ -19,6 +19,7 @@ // #import +#import "RKDynamicMappingMatcher.h" /** The `RKConnectionDescription` class describes a means for connecting a Core Data relationship. Connections can be established either by foreign key, in which case one or more attribute values on the source entity correspond to matching values on the destination entity, or by key path, in which case a key path is evaluated on the object graph to obtain a value for the relationship. Connection objects are used by instances of `RKRelationshipConnectionOperation` to connect a relationship of a given managed object. @@ -156,4 +157,9 @@ */ @property (nonatomic, copy) NSPredicate *predicate; +/** + An optional matcher that filters the source object to be connected. + */ +@property (nonatomic, strong) RKDynamicMappingMatcher* matcher; + @end diff --git a/Code/CoreData/RKRelationshipConnectionOperation.m b/Code/CoreData/RKRelationshipConnectionOperation.m index 0817a6b0..e443c3f2 100644 --- a/Code/CoreData/RKRelationshipConnectionOperation.m +++ b/Code/CoreData/RKRelationshipConnectionOperation.m @@ -139,6 +139,10 @@ static NSDictionary *RKConnectionAttributeValuesWithObject(RKConnectionDescripti - (id)findConnected { id connectionResult = nil; + + if (self.connection.matcher && ![self.connection.matcher matches:self.managedObject]) + return nil; + if ([self.connection isForeignKeyConnection]) { NSDictionary *attributeValues = RKConnectionAttributeValuesWithObject(self.connection, self.managedObject); NSSet *managedObjects = [self.managedObjectCache managedObjectsWithEntity:[self.connection.relationship destinationEntity] diff --git a/Tests/Logic/CoreData/RKRelationshipConnectionOperationTest.m b/Tests/Logic/CoreData/RKRelationshipConnectionOperationTest.m index c4187b46..bfa0981c 100644 --- a/Tests/Logic/CoreData/RKRelationshipConnectionOperationTest.m +++ b/Tests/Logic/CoreData/RKRelationshipConnectionOperationTest.m @@ -256,4 +256,51 @@ expect(secondChild.friends).to.equal(expectedFriends); } +- (void)testConnectionMatcher +{ + RKHuman *human = [RKTestFactory insertManagedObjectForEntityForName:@"Human" inManagedObjectContext:nil withProperties:nil]; + human.sex = @"female"; + RKCat *asia = [RKTestFactory insertManagedObjectForEntityForName:@"Cat" inManagedObjectContext:nil withProperties:nil]; + asia.sex = @"female"; + RKCat *lola = [RKTestFactory insertManagedObjectForEntityForName:@"Cat" inManagedObjectContext:nil withProperties:nil]; + lola.sex = @"female"; + RKCat *roy = [RKTestFactory insertManagedObjectForEntityForName:@"Cat" inManagedObjectContext:nil withProperties:nil]; + roy.sex = @"male"; + + RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Human" inManagedObjectStore:[RKTestFactory managedObjectStore]]; + [mapping addConnectionForRelationship:@"cats" connectedBy:@"sex"]; + RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new]; + RKConnectionDescription *connection = [mapping connectionForRelationship:@"cats"]; + + RKEntityMapping *catMapping = [RKEntityMapping mappingForEntityForName:@"Cat" inManagedObjectStore:[RKTestFactory managedObjectStore]]; + connection.matcher = [[RKDynamicMappingMatcher alloc] initWithKeyPath:@"sex" expectedValue:@"male" objectMapping:catMapping]; + + RKRelationshipConnectionOperation *operation = [[RKRelationshipConnectionOperation alloc] initWithManagedObject:human connection:connection managedObjectCache:managedObjectCache]; + [operation start]; + assertThat(human.cats, hasCountOf(0)); +} + +- (void)testConnectionPredicate +{ + RKHuman *human = [RKTestFactory insertManagedObjectForEntityForName:@"Human" inManagedObjectContext:nil withProperties:nil]; + human.sex = @"female"; + + RKCat *asia = [RKTestFactory insertManagedObjectForEntityForName:@"Cat" inManagedObjectContext:nil withProperties:@{@"birthYear": @2011}]; + asia.sex = @"female"; + RKCat *lola = [RKTestFactory insertManagedObjectForEntityForName:@"Cat" inManagedObjectContext:nil withProperties:@{@"birthYear": @2012}]; + lola.sex = @"female"; + + RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Human" inManagedObjectStore:[RKTestFactory managedObjectStore]]; + [mapping addConnectionForRelationship:@"cats" connectedBy:@"sex"]; + RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new]; + RKConnectionDescription *connection = [mapping connectionForRelationship:@"cats"]; + connection.predicate = [NSPredicate predicateWithFormat:@"birthYear = 2011"]; + + + RKRelationshipConnectionOperation *operation = [[RKRelationshipConnectionOperation alloc] initWithManagedObject:human connection:connection managedObjectCache:managedObjectCache]; + [operation start]; + assertThat(human.cats, hasCountOf(1)); + assertThat(human.cats, hasItems(asia, nil)); +} + @end