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";
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity];
NSDictionary *expected = @{ @"egg_count" : @2 };
id<BUYObject> object = [nestRelationship buy_valueForJSON:expected object:branch];
NSDictionary *actual = [nestRelationship buy_JSONForValue:object];
Nest *nest = [nestRelationship buy_valueForJSON:expected object:branch];
XCTAssertEqual(branch, [nest branch]);
NSDictionary *actual = [nestRelationship buy_JSONForValue:nest];
XCTAssertEqualObjects(actual, expected);
}
......@@ -209,9 +210,9 @@ static NSString * const RootEntity = @"Root";
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *nestRelationship = [self relationshipWithName:@"nest" forEntity:BranchEntity];
NSDictionary *json = @{ @"bird_id" : @501 };
id object = [nestRelationship buy_valueForJSON:json object:branch];
XCTAssertEqualObjects(@501, [[object bird] identifier]);
id actual = [nestRelationship buy_JSONForValue:object];
Nest *nest = [nestRelationship buy_valueForJSON:json object:branch];
XCTAssertEqualObjects(@501, [[nest bird] identifier]);
id actual = [nestRelationship buy_JSONForValue:nest];
XCTAssertEqualObjects(actual, json);
}
......@@ -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 jan1_2000]] tags:[self tagsWithIndexes:@[@12, @0, @8, @4]]]]];
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);
}
......
......@@ -43,6 +43,7 @@
@interface Bird : TestModel
@property (nonatomic) NSNumber *identifier;
@property (nonatomic) NSString *colour;
@property (nonatomic) NSSet<Nest *> *nests;
@property (nonatomic) NSSet<Researcher *> *researchers;
+ (instancetype)birdWithIdentifier:(NSNumber *)identifier;
@end
......@@ -58,6 +59,7 @@
@end
@interface Leaf : TestModel
@property (nonatomic) Branch *branch;
@property (nonatomic) NSDate *date;
@property (nonatomic) NSSet<NSString *> *tags;
@end
......
......@@ -186,17 +186,24 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
}
// 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;
// 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.
if (self.encodesIdInJSON) {
return [modelManager buy_objectWithEntityName:entityName identifier:JSON];
result = [object.modelManager buy_objectWithEntityName:entityName identifier:JSON];
}
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
......@@ -210,7 +217,7 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
}
// 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;
NSArray<id<BUYObject>> *array;
......@@ -219,10 +226,18 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
// 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 (self.encodesIdInJSON) {
array = [modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
array = [object.modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
}
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`).
......@@ -246,10 +261,10 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
id value = nil;
if ([JSON buy_isValidObject]) {
if (self.isToMany) {
value = [self buy_collectionForJSON:JSON modelManager:object.modelManager];
value = [self buy_collectionForJSON:JSON object:object];
}
else {
value = [self buy_objectForJSON:JSON modelManager:object.modelManager];
value = [self buy_objectForJSON:JSON object:object];
}
}
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