首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与Vapor 4的父子关系

问与Vapor 4的父子关系
EN

Stack Overflow用户
提问于 2020-06-16 22:41:06
回答 2查看 970关注 0票数 2

我想在Vapor 4中设置League和Team之间的父子关系。我可以很好地创建League,但当我尝试创建一个新团队时,如下所示:

代码语言:javascript
复制
{
    "name": "Chicago Bulls",
    "league_id": "C21827C2-8FAD-4A89-B8D3-A3E62E421258"
}

我得到了这个错误:

代码语言:javascript
复制
{
    "error": true,
    "reason": "Value of type 'League' required for key 'league'."
}

我只想用一个引用Leagues表中的League的league_id初始化一个Team。我在Vapor 3中可以正常工作,但在Vapor 4中似乎不能正确使用。

请参阅下面的模型和迁移。

League型号:

代码语言:javascript
复制
final class League: Model, Content {

    init() {}
    static let schema = "Leagues"

    @ID(key: .id) var id: UUID?
    @Field(key: .name) var name: String
    @Field(key: .sport) var sport: String

    @Children(for: \.$league) var teams: [Team]

    init(name: String, sport: String) {
        self.name = name
        self.sport = sport
    }

}

Team型号:

代码语言:javascript
复制
final class Team: Model, Content {

    init() {}
    static let schema = "Teams"

    @ID(key: .id) var id: UUID?
    @Field(key: .name) var name: String

    @Parent(key: .leagueId) var league: League

    init(id: UUID? = nil, name: String, leagueId: UUID) throws {
        self.id = id
        self.name = name
        self.$league.id = leagueId
    }

}

CreateLeague迁移:

代码语言:javascript
复制
struct CreateLeague: Migration {

    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(League.schema)
            .id()
            .field(.name, .string, .required)
            .field(.sport, .string, .required)
            .create()
    }

    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(League.schema).delete()
    }

}

CreateTeam迁移:

代码语言:javascript
复制
struct CreateTeam: Migration {

    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(Team.schema)
            .id()
            .field(.name, .string, .required)
            .field(.leagueId, .uuid, .required, .references(League.schema, .id))
            .create()
    }

    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(Team.schema).delete()
    }

}

TeamsController

代码语言:javascript
复制
class TeamsController: RouteCollection {

    func boot(routes: RoutesBuilder) throws {
        let teamsRoute = routes.grouped("teams")
        teamsRoute.post(use: createTeam)
    }

    func createTeam(req: Request) throws -> EventLoopFuture<Team> {
        let team = try req.content.decode(Team.self)
        return team.save(on: req.db).map { team }
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-16 23:27:02

这是失败的,因为属性包装器覆盖模型的JSON解码的方式。您有两个选择。您可以发送JSON Fluent expects:

代码语言:javascript
复制
{
    "name": "Chicago Bulls",
    "league": {
        "id": "C21827C2-8FAD-4A89-B8D3-A3E62E421258"
    }
}

或者,您可以创建一个新类型CreateTeamData,它与您期望发送的JSON相匹配,然后手动创建一个Team。我更喜欢第二条路线:

代码语言:javascript
复制
struct CreateTeamData: Content {
  let name: String
  let leagueID: UUID
}

func createTeam(req: Request) throws -> EventLoopFuture<Team> {
    let data = try req.content.decode(CreateTeamData.self)
    let team = Team(name: data.name, leagueID: data.leagueID)
    return team.save(on: req.db).map { team }
}
票数 8
EN

Stack Overflow用户

发布于 2020-06-16 22:57:04

您的迁移在我看来很好。尝试将Team模型的初始化更改为:

代码语言:javascript
复制
init(id: UUID? = nil, name: String, leagueId: League.IDValue) throws {
    self.id = id
    self.name = name
    self.$league.id = leagueId
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62411157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档