Commit 0fb34f84 by Brent Gulanowski

Various improvements.

Reorganize private methods; add comments; consistent naming.

Simplify object -> JSON serialization.

Also fix a bug in `-buy_JSONForObject:` at the same time. Was incorrectly sending `-valueForKey:` to the wrong object (we already had the object who owns the identifier).
parent 74840977
......@@ -164,21 +164,26 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
@implementation NSRelationshipDescription (BUYAdditions)
#pragma mark - Helpers
- (NSString *)encodesIdSuffix
{
return (self.isToMany ? @"_ids" : @"_id");
}
- (BOOL)buy_encodesIdInJSON
// array -> (ordered)set
- (id)buy_transformArray:(NSArray<id<BUYObject>> *)array
{
return [self.JSONPropertyKey hasSuffix:[self encodesIdSuffix]];
return self.isOrdered ? [NSOrderedSet orderedSetWithArray:array] : [NSSet setWithArray:array];
}
- (id)buy_transformArray:(NSArray<id<BUYObject>> *)array
// (ordered)set -> array
- (NSArray *)buy_arrayForCollection:(id)collection
{
return self.isOrdered ? [NSOrderedSet orderedSetWithArray:array] : [NSSet setWithArray:array];
return self.ordered ? [collection array] : [collection allObjects];
}
// JSON -> model
- (id)buy_objectForJSON:(id)JSON modelManager:(id<BUYModelManager>)modelManager
{
NSString *entityName = self.destinationEntity.name;
......@@ -192,7 +197,26 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
}
}
- (id)buy_collectionForJSON:(NSArray *)JSON object:(id<BUYObject>)object
// model -> JSON
- (id)buy_JSONForObject:(NSObject<BUYObject> *)object
{
// JSON generation for a relationship depends on the rules defined in the model.
// The model can explicitly specify using an `id` encoding.
// Alternately, if the relationship is compatible, encode the entire object.
// We do not encode related objects unless three conditions are satisfied:
// 1. the relationship is not many-to-many
// 2. the inverse relationship is not an ownership relationship
// (this is inferred from the `NSCascadeDeleteRule` used by owning objects)
// 3. the relationship is to a "private" entity (not known to the API)
id json = nil;
if (!self.inverseRelationship || self.inverseRelationship.allowsInverseEncoding) {
json = [self.destinationEntity buy_JSONForObject:object];
}
return json;
}
// JSON -> (ordered)set (of models)
- (id)buy_collectionForJSON:(NSArray *)JSON modelManager:(id<BUYModelManager>)modelManager
{
NSString *entityName = self.destinationEntity.name;
NSArray<id<BUYObject>> *array;
......@@ -201,16 +225,24 @@ 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 = [object.modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
array = [modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
}
else {
array = [object.modelManager buy_objectsWithEntityName:entityName JSONArray:JSON];
array = [modelManager buy_objectsWithEntityName:entityName JSONArray:JSON];
}
// Transform the array to the correct container type (`NSSet` or `NSOrderedSet`).
return [self buy_transformArray:array];
}
// (ordered)set (of models) -> JSON
- (NSArray *)buy_JSONForCollection:(id)collection
{
NSArray *array = [self buy_arrayForCollection:collection];
return [self.destinationEntity buy_JSONForArray:array];
}
#pragma mark - Property Additions Overrides
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object
{
......@@ -218,9 +250,9 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
// The logic for decoding JSON is slightly different for to-one and to-many relationships.
// NOTE: by default, without a caching system, inverse relationships are not supported.
if (JSON && ![JSON isEqual:[NSNull null]]) {
if ([JSON buy_isValidObject]) {
if (self.isToMany) {
return [self buy_collectionForJSON:JSON object:object];
return [self buy_collectionForJSON:JSON modelManager:object.modelManager];
}
else {
return [self buy_objectForJSON:JSON modelManager:object.modelManager];
......@@ -233,43 +265,24 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
- (id)buy_JSONForValue:(id)value
{
return self.toMany ? [self buy_JSONForCollection:value] : [self buy_JSONForObject:value];
}
- (NSArray *)buy_JSONForCollection:(id)collection
{
if (self.manyToMany) {
return nil;
}
NSArray *array = [self buy_arrayForCollection:collection];
return self.encodesIdInJSON ? [array valueForKey:@"identifier"] : [self.destinationEntity buy_JSONForArray:array];
}
- (NSArray *)buy_arrayForCollection:(id)collection
{
return self.ordered ? [collection array] : [collection allObjects];
}
- (id)buy_JSONForObject:(NSObject<BUYObject> *)object
{
// JSON generation for a relationship depends on the rules defined in the model.
// The model can explicitly specify using an `id` encoding.
// Alternately, if the relationship is compatible, encode the entire object.
// We do not encode related objects unless three conditions are satisfied:
// 1. the relationship is not many-to-many
// 2. the inverse relationship is not an ownership relationship
// (this is inferred from the `NSCascadeDeleteRule` used by owning objects)
// 3. the relationship is to a "private" entity (not known to the API)
id json = nil;
if (self.encodesIdInJSON) {
return [[object valueForKey:self.name] identifier];
json = [value valueForKey:NSStringFromSelector(@selector(identifier))];
}
else if (!self.inverseRelationship || self.inverseRelationship.allowsInverseEncoding) {
return [self.destinationEntity buy_JSONForObject:object];
else if (self.toMany && ! self.manyToMany) {
json = [self buy_JSONForCollection:value];
}
else {
return nil;
json = [self buy_JSONForObject:value];
}
return json;
}
#pragma mark - Properties
- (BOOL)buy_encodesIdInJSON
{
return [self.JSONPropertyKey hasSuffix:[self encodesIdSuffix]];
}
- (BOOL)buy_isManyToMany
......@@ -293,7 +306,7 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
return nil;
}
- (id)buy_reverseTransformedJSONValue:(id)value
- (id)buy_JSONForValue:(id)value
{
return nil;
}
......@@ -302,8 +315,6 @@ static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
#pragma mark -
// We could be really clever here and use an algorithm for string transformation
// but it's not worth it right now.
@implementation NSObject (BUYValueTransforming)
+ (NSString *)buy_JSONValueTransformerName
......
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