It's possible to create relation controllers to attach/detach existing entites
- Create relation controller methods:
struct TagsForTodoRelationController {
func createRelation(req: Request) throws -> EventLoopFuture<Tag.Output> {
try RelationsController<Tag.Output>().createRelation(
req: req,
relationKeyPath: \Todo.$tags)
}
func deleteRelation(req: Request) throws -> EventLoopFuture<Tag.Output> {
try RelationsController<Tag.Output>().deleteRelation(
req: req,
relationKeyPath: \Todo.$tags)
}
}
- Add methods to routes builder:
app.group("todos", Todo.idPath, "relation_name", "tags", Tag.idPath, "relation") {
let controller = TagsForTodoRelationController()
$0.on(.POST, use: controller.createRelation)
$0.on(.DELETE, use: controller.deleteRelation)
}
Will result in:
HTTP Method | Route | Result |
---|---|---|
POST | /todos/:todoId/relation_name/tags/:tagId/relation | Attach instances with relation |
DELETE | /todos/:todoId/relation_name/tags/:tagId/relation | Detach instances using relation |
Everything is the same as with RelatedResourceController.
If root Model conforms to Vapor's Authenticatable protocol, there is a way to add relation controller so that the root model would be resolved from authenticator istead of looked up by ID.
This a quick way for attach something to current user.
- Create relation controller with
.requireAuth()
as resolver parameter:
struct MyAssignedTodosRelationController {
func createRelation(req: Request) throws -> EventLoopFuture<Todo.Output> {
try RelationsController<Todo.Output>().createRelation(
resolver: .requireAuth(),
req: req,
relationKeyPath: \User.$assignedTodos)
}
func deleteRelation(req: Request) throws -> EventLoopFuture<Todo.Output> {
try RelationsController<Todo.Output>().deleteRelation(
resolver: .requireAuth(),
req: req,
relationKeyPath: \User.$assignedTodos)
}
}
- Setup route
app.group("users") {
// Make sure that authenticator and auth guard middlewares are added to the route builder
let auth = $0.grouped(Authenticator(), User.guardMiddleware())
auth.group("me", "assigned", "todos") {
$0.group(Todo.idPath, "relation") {
let controller = MyAssignedTodosRelationController()
$0.on(.POST, use: controller.createRelation)
$0.on(.DELETE, use: controller.deleteRelation)
}
}
}