swift - 在 vapor 3 中创建父子关系

标签 swift parent-child vapor

我正在使用 Vapor 3 来尝试创建一个示例项目,其中我有一道菜, parent ,以及对菜的评论, child 。我看到的所有教程都不是很清楚如何创建关系,或者他们在推测中使用它与 leaf。我不想为此使用 leaf,我只是想在我给这道菜 id 时能够显示所有评论,而且它似乎与 vapor 2 不同。 我的 2 个模型是 Dish 和 Review Dish.swift:父级,

import Foundation
import Vapor
import FluentSQLite

final class Dish: Content {
    var id: Int?
    var name: String
    var course: String
    var price: Double
    var imageURL: String
    var description: String

    init(name: String, course: String, price: Double, imageURL: String, description: String) {
        self.name = name
        self.course = course
        self.price = price
        self.imageURL = imageURL
        self.description = description

    }

}

extension Dish {
    var reviews: Children<Dish, Review> {
        return children(\.dishId)
    }
}

extension Dish: Parameter { }

extension Dish: SQLiteModel {
    static let entity: String = "Dishes"
}

extension Dish: Migration { }

Review.swift, child ,

import Foundation
import Vapor
import FluentSQLite

final class Review: Content {

    var id: Int?
    var title: String
    var body: String
    var dishId: Dish.ID

    init(title: String, body: String, dishId: Dish.ID) {
        self.title = title
        self.body = body
        self.dishId = dishId
    }

}

extension Review {
    var dish: Parent<Review, Dish> {
        return parent(\.dishId)
    }
}

extension Review: Migration { }

extension Review: SQLiteModel {
    static let entity: String = "Reviews"
}

extension Review: Parameter { }

Dish 的 Controller ,DishController,

import Foundation
import Vapor
import FluentSQLite

class DishesController: RouteCollection {

    func boot(router: Router) throws {
        let dishesRoutes = router.grouped("api/dishes")
        dishesRoutes.get("/", use: getAll)
        dishesRoutes.get(Dish.parameter, use: getById)
        dishesRoutes.post(Dish.self, at: "/", use: createDish)
        dishesRoutes.delete(Dish.parameter, use: deleteDish)
    }

    func deleteDish(req: Request) throws -> Future<Dish> {
        return try req.parameters.next(Dish.self).delete(on: req)
    }


    func createDish(req: Request, dish: Dish) -> Future<Dish> {
        return dish.save(on: req)
    }

    func getAll(req: Request) -> Future<[Dish]> {
        return Dish.query(on: req).all()
    }

    func getById(req: Request) throws -> Future<Dish> {
        return try req.parameters.next(Dish.self)
    }


}

和审查的 Controller 。评论 Controller ,

import Foundation
import Vapor
import FluentSQLite

class ReviewController: RouteCollection {
    func boot(router: Router) throws {
        let reviewRoutes = router.grouped("api/reviews")


        reviewRoutes.get("/", use: getAll)
        reviewRoutes.get(Review.parameter, use: getById)
        reviewRoutes.post(Review.self, at: "/", use: createReview)
        reviewRoutes.delete(Review.parameter, use: deleteReview)

    }


    func deleteReview(req: Request) throws -> Future<Review> {
        return try req.parameters.next(Review.self).delete(on: req)
    }

    func createReview(req: Request, review: Review) -> Future<Review> {
        return review.save(on: req)
    }


    func getAll(req: Request) -> Future<[Review]> {
        return Review.query(on: req).all()
    }

    func getById(req: Request) throws -> Future<Review> {
        return try req.parameters.next(Review.self)
    }
}

这是 routes.swift,

import Vapor


/// Register your application's routes here.
public func routes(_ router: Router) throws {


    router.get("/reviews", Dish.parameter,"dish") { request -> Future<Dish> in

        return try request.parameters.next(Review.self).flatMap(to: Dish.self) { review in

            return review.dish.get(on: request)
        }
    }


    let dishesController = DishesController()
    try router.register(collection: dishesController)
    let reviewController = ReviewController()
    try router.register(collection: reviewController)

}

我只想要一个简单的一对多关系,其中一道菜可以有很多评论,但是当我使用 postman 尝试访问特定菜的评论时,我得到的只是一个错误。我知道我在 postman 中使用了正确的语法,因为我可以很好地使用来自 Controller 的所有其他请求,只是不能用于关系。请告诉我我错过了什么,因为我对自己做错了什么感到困惑。如果还有什么我可以补充的,请询问。 非常感谢

最佳答案

如果您想访问特定菜肴的所有评论,请尝试以下代码。

router.get("/dish", Dish.parameter,"reviews") { request -> Future<[Review]> in
        return try request.parameters.next(Dish.self).flatMap(to: [Review].self) { (dish) in
                    return try dish.reviews.query(on: request).all()
                }
}

现在在 postman 中,传递一个 dish id 如下:

GET: http://localhost:8080/dish/1/reviews

关于swift - 在 vapor 3 中创建父子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53056799/

相关文章:

ios - 表/ Collection View 的水平滚动

angular - 如何添加到当前路线并导航 - Angular

swift - 通过 Vapor Fluent-MySQL 中的迁移更改 VARCHAR 字段

swift - Vapor,使用 PostgreSQL 流畅地保存/创建复杂模型

swift - 将域指向在 OS X 服务器上运行的 Web 应用程序(例如 Kitura、perfect、vapor server)

ios - 在快速完成所有后台进程后执行功能

swift - 无法将类型 'NSArray' 的值转换为预期的参数类型 '[Any]!'

ios - 使用核心数据完全不相关的错误

javascript - 阻止对父级的相同域 iframe 访问

在 C 中通过 fork() 创建子进程