From f288d14ace50c8f264acfc9f112c6432796fff3c Mon Sep 17 00:00:00 2001 From: Koray Koska Date: Wed, 10 May 2017 22:12:11 +0200 Subject: [PATCH] Add relationship handling for resource creation --- .../Resources/JsonApiResourceController.swift | 27 +++++++++++++++++-- .../VaporJsonApi/Response/JsonApiError.swift | 11 ++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Sources/VaporJsonApi/Resources/JsonApiResourceController.swift b/Sources/VaporJsonApi/Resources/JsonApiResourceController.swift index 3099e59..fdb3b98 100644 --- a/Sources/VaporJsonApi/Resources/JsonApiResourceController.swift +++ b/Sources/VaporJsonApi/Resources/JsonApiResourceController.swift @@ -171,10 +171,33 @@ public extension JsonApiResourceController { let node = bodyData?["attributes"]?.makeNode() var resource = try Resource(node: node) - // TODO: Set relationships + // TODO: Check jsonapi document for correct to-many relationship handling if let relationships = bodyData?["relationships"]?.object { for r in relationships { - + // Get relationships + let parents = try resource.parentRelationships() + let children = try resource.childrenRelationships() + let siblings = try resource.siblingsRelationships() + + if let parent = parents[r.key] { + guard let id = r.value.object?["id"]?.string, let type = r.value.object?["type"]?.string else { + throw JsonApiBadRequestError(title: "Bad Request", detail: "The relationship \(r.key) must have a type and id value.") + } + guard let p = try parent.type.find(id) else { + throw JsonApiRecordNotFoundError(id: id) + } + guard let setter = parent.setter else { + throw JsonApiRelationshipNotAllowedError(relationship: type) + } + + try setter(p) + } else if let _ = children[r.key] { + throw JsonApiBadRequestError(title: "Setting to-many relationships not allowed", detail: "You set to-many relationships in the same step as creating a resource right now. You tried to set \(r.key) for this resource.") + } else if let _ = siblings[r.key] { + throw JsonApiBadRequestError(title: "Setting to-many relationships not allowed", detail: "You set to-many relationships in the same step as creating a resource right now. You tried to set \(r.key) for this resource.") + } else { + throw JsonApiRelationshipNotAllowedError(relationship: r.key) + } } } try resource.save() diff --git a/Sources/VaporJsonApi/Response/JsonApiError.swift b/Sources/VaporJsonApi/Response/JsonApiError.swift index 34b17bd..9847e28 100644 --- a/Sources/VaporJsonApi/Response/JsonApiError.swift +++ b/Sources/VaporJsonApi/Response/JsonApiError.swift @@ -276,6 +276,17 @@ public class JsonApiParameterNotAllowedError: JsonApiGeneralError { } } +public class JsonApiRelationshipNotAllowedError: JsonApiGeneralError { + + public init(title: String, detail: String) { + super.init(status: Status.badRequest, code: String(Status.badRequest.statusCode), title: title, detail: detail) + } + + public convenience init(relationship: String) { + self.init(title: "Relationship not allowed", detail: "\(relationship) is not allowed.") + } +} + public class JsonApiParameterMissingError: JsonApiGeneralError { public init(title: String, detail: String) {