亲子关系与蒸气4

时间:2020-06-16 14:41:06

标签: swift vapor vapor-fluent

我想在Vapor 4中建立LeagueTeam之间的父子关系。我可以很好地创建一个League,但是当我尝试创建一个新的像这样的团队:

{
    "name": "Chicago Bulls",
    "league_id": "C21827C2-8FAD-4A89-B8D3-A3E62E421258"
}

我收到此错误:

{
    "error": true,
    "reason": "Value of type 'League' required for key 'league'."
}

我只想用一个Team初始化一个league_id表中的一个League的{​​{1}}。我在Vapor 3中使用了此功能,但似乎在Vapor 4中无法正确使用。

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

Leagues模型:

League

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

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

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

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

2 个答案:

答案 0 :(得分:5)

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

{
    "name": "Chicago Bulls",
    "league": {
        "id": "C21827C2-8FAD-4A89-B8D3-A3E62E421258"
    }
}

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

struct CreateTeamData: Content {
  let name: String
  let leagueID: UUID
}

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

答案 1 :(得分:0)

您的迁移对我来说似乎还不错。尝试将Team模型的初始化更改为:

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