在 vapor 3 中创建 parent child 关系

creating a parent child relationship in vapor 3

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

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 的控制器,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)
    }


}

和负责审查的控制器。评论控制器,

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)

}

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

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

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()
                }
}

现在在邮递员中,传递一个菜号如下:

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