Commit 74858565 by Brent Gulanowski Committed by GitHub

Merge pull request #239 from Shopify/bugfix/inverse-relationships

Assign inverse values for 1-to-1 and 1-to-N relationships
parents a239ec86 2d90cf90
...@@ -199,8 +199,9 @@ static NSString * const RootEntity = @"Root"; ...@@ -199,8 +199,9 @@ static NSString * const RootEntity = @"Root";
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil]; Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity]; NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity];
NSDictionary *expected = @{ @"egg_count" : @2 }; NSDictionary *expected = @{ @"egg_count" : @2 };
id<BUYObject> object = [nestRelationship buy_valueForJSON:expected object:branch]; Nest *nest = [nestRelationship buy_valueForJSON:expected object:branch];
NSDictionary *actual = [nestRelationship buy_JSONForValue:object]; XCTAssertEqual(branch, [nest branch]);
NSDictionary *actual = [nestRelationship buy_JSONForValue:nest];
XCTAssertEqualObjects(actual, expected); XCTAssertEqualObjects(actual, expected);
} }
...@@ -209,9 +210,9 @@ static NSString * const RootEntity = @"Root"; ...@@ -209,9 +210,9 @@ static NSString * const RootEntity = @"Root";
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil]; Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity]; NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity];
NSDictionary *json = @{ @"bird_id" : @501 }; NSDictionary *json = @{ @"bird_id" : @501 };
id object = [nestRelationship buy_valueForJSON:json object:branch]; Nest *nest = [nestRelationship buy_valueForJSON:json object:branch];
XCTAssertEqualObjects(@501, [[object bird] identifier]); XCTAssertEqualObjects(@501, [[nest bird] identifier]);
id actual = [nestRelationship buy_JSONForValue:object]; id actual = [nestRelationship buy_JSONForValue:nest];
XCTAssertEqualObjects(actual, json); XCTAssertEqualObjects(actual, json);
} }
...@@ -225,7 +226,10 @@ static NSString * const RootEntity = @"Root"; ...@@ -225,7 +226,10 @@ static NSString * const RootEntity = @"Root";
[self leafWithDate:[self dateWithComponents:[self june21_1970]] tags:[self tagsWithIndexes:@[@9]]], [self leafWithDate:[self dateWithComponents:[self june21_1970]] tags:[self tagsWithIndexes:@[@9]]],
[self leafWithDate:[self dateWithComponents:[self jan1_2000]] tags:[self tagsWithIndexes:@[@12, @0, @8, @4]]]]]; [self leafWithDate:[self dateWithComponents:[self jan1_2000]] tags:[self tagsWithIndexes:@[@12, @0, @8, @4]]]]];
id json = [leafRelationship buy_JSONForValue:branch.leaves]; id json = [leafRelationship buy_JSONForValue:branch.leaves];
id actual = [leafRelationship buy_valueForJSON:json object:branch]; NSSet<Leaf *> *actual = [leafRelationship buy_valueForJSON:json object:branch];
for (Leaf *leaf in actual) {
XCTAssertEqualObjects(leaf.branch, branch);
}
XCTAssertEqualObjects(actual, branch.leaves); XCTAssertEqualObjects(actual, branch.leaves);
} }
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
@interface Bird : TestModel @interface Bird : TestModel
@property (nonatomic) NSNumber *identifier; @property (nonatomic) NSNumber *identifier;
@property (nonatomic) NSString *colour; @property (nonatomic) NSString *colour;
@property (nonatomic) NSSet<Nest *> *nests;
@property (nonatomic) NSSet<Researcher *> *researchers; @property (nonatomic) NSSet<Researcher *> *researchers;
+ (instancetype)birdWithIdentifier:(NSNumber *)identifier; + (instancetype)birdWithIdentifier:(NSNumber *)identifier;
@end @end
...@@ -58,6 +59,7 @@ ...@@ -58,6 +59,7 @@
@end @end
@interface Leaf : TestModel @interface Leaf : TestModel
@property (nonatomic) Branch *branch;
@property (nonatomic) NSDate *date; @property (nonatomic) NSDate *date;
@property (nonatomic) NSSet<NSString *> *tags; @property (nonatomic) NSSet<NSString *> *tags;
@end @end
......
...@@ -186,17 +186,24 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type) ...@@ -186,17 +186,24 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
} }
// JSON -> model // JSON -> model
- (id)buy_objectForJSON:(id)JSON modelManager:(id<BUYModelManager>)modelManager - (id)buy_objectForJSON:(id)JSON object:(id<BUYObject>)object
{ {
id result;
NSString *entityName = self.destinationEntity.name; NSString *entityName = self.destinationEntity.name;
// If we are expecting an object `id` the object should already exist. // If we are expecting an object `id` the object should already exist.
// Otherwise let the object context decide how to resolve the object and update it. // Otherwise let the object context decide how to resolve the object and update it.
if (self.encodesIdInJSON) { if (self.encodesIdInJSON) {
return [modelManager buy_objectWithEntityName:entityName identifier:JSON]; result = [object.modelManager buy_objectWithEntityName:entityName identifier:JSON];
} }
else { else {
return [modelManager buy_objectWithEntityName:entityName JSONDictionary:JSON]; result = [object.modelManager buy_objectWithEntityName:entityName JSONDictionary:JSON];
} }
#if !CORE_DATA_PERSISTENCE
if (self.inverseRelationship && !self.inverseRelationship.isToMany) {
[result setValue:object forKey:self.inverseRelationship.name];
}
#endif
return result;
} }
// model -> JSON // model -> JSON
...@@ -210,7 +217,7 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type) ...@@ -210,7 +217,7 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
} }
// JSON -> (ordered)set (of models) // JSON -> (ordered)set (of models)
- (id)buy_collectionForJSON:(NSArray *)JSON modelManager:(id<BUYModelManager>)modelManager - (id)buy_collectionForJSON:(NSArray *)JSON object:(id<BUYObject>)object
{ {
NSString *entityName = self.destinationEntity.name; NSString *entityName = self.destinationEntity.name;
NSArray<id<BUYObject>> *array; NSArray<id<BUYObject>> *array;
...@@ -219,10 +226,18 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type) ...@@ -219,10 +226,18 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
// Otherwise, let the object context decide how to resolve the objects and update them. // Otherwise, let the object context decide how to resolve the objects and update them.
// If device caching is not provided, this will return nothing. // If device caching is not provided, this will return nothing.
if (self.encodesIdInJSON) { if (self.encodesIdInJSON) {
array = [modelManager buy_objectsWithEntityName:entityName identifiers:JSON]; array = [object.modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
} }
else { else {
array = [modelManager buy_objectsWithEntityName:entityName JSONArray:JSON]; array = [object.modelManager buy_objectsWithEntityName:entityName JSONArray:JSON];
#if !CORE_DATA_PERSISTENCE
if (self.inverseRelationship && !self.inverseRelationship.isToMany) {
NSString *inverseKey = self.inverseRelationship.name;
for (id related in array) {
[related setValue:object forKey:inverseKey];
}
}
#endif
} }
// Transform the array to the correct container type (`NSSet` or `NSOrderedSet`). // Transform the array to the correct container type (`NSSet` or `NSOrderedSet`).
...@@ -246,10 +261,10 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type) ...@@ -246,10 +261,10 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
id value = nil; id value = nil;
if ([JSON buy_isValidObject]) { if ([JSON buy_isValidObject]) {
if (self.isToMany) { if (self.isToMany) {
value = [self buy_collectionForJSON:JSON modelManager:object.modelManager]; value = [self buy_collectionForJSON:JSON object:object];
} }
else { else {
value = [self buy_objectForJSON:JSON modelManager:object.modelManager]; value = [self buy_objectForJSON:JSON object:object];
} }
} }
return value; return value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment