создание отношений родитель-ребенок в паре 3 - PullRequest
0 голосов
/ 30 октября 2018

Я использую Vapor 3, чтобы попытаться создать просто пример проекта, в котором у меня есть блюдо, родитель и отзывы о блюде, ребенок. Все учебные пособия, которые я видел, не очень ясно о том, как создать отношения, или они используют это в предположении с листа. Я не хочу использовать лист для этого, я просто хочу иметь возможность показать все отзывы, когда для блюда, когда я даю его идентификатор, и кажется, что он отличается от того, что было для пара 2. Мои 2 модели - Блюдо и Обзор 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, ребенок,

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


}

и контроллер для обзоров. ReviewController,

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

это route.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)

}

Я просто хочу, чтобы между одним и несколькими блюдами было много отзывов, но когда я использую почтальон, чтобы получить доступ к обзорам конкретного блюда, я получаю только ошибку. Я знаю, что я использовал правильный синтаксис в почтальоне, потому что я могу использовать все остальные запросы от контроллеров просто отлично, но не для отношений. Пожалуйста, скажите мне, что мне не хватает, потому что я запутался в том, что я делаю неправильно. Если есть что-то еще, что я могу добавить, пожалуйста, спросите. Большое спасибо

1 Ответ

0 голосов
/ 30 октября 2018

Если вы хотите получить доступ ко всем отзывам для конкретного блюда, попробуйте следующий код.

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

...