为什么运行此代码时没有在 vapor 中创建数据透视条目?

Why is no pivot entry being created in vapor when this code runs?

希望有人能看到我在这里遗漏了什么。我正在尝试在用户和锦标赛之间创建一个枢轴 table 条目,在我的应用程序中有两个 table。如您所料,用户在路由期间获得授权,最终以这种方法结束(我尝试从两侧创建枢轴,如注释行所示):

    func acceptInvitation(req: Request) -> EventLoopFuture<Response> {
        let user : User = req.auth.get(User.self)!
        let uId : UUID = user.id!
        let iId = UUID.init(uuidString: req.parameters.get("iId")!)
        return Invitation.query(on: req.db)
            .filter(\.$id == iId!)
            .with(\.$owner)
            .first().flatMap { i -> EventLoopFuture<Response> in
                i?.acceptances!.append((uId))
                i?.update(on: req.db)
                i!.owner.acceptances!.append(uId)
                i?.owner.update(on: req.db)
                i?.owner.$tournamentPlayers.attach(user, on: req.db)
//                user.$playerTournaments.attach(i!.owner, on: req.db)
                return req.eventLoop.future(req.redirect(to: "/")).encodeResponse(for: req)
            }
    }

迁移正常,postgres 显示为:

vapor-database=# \d tournament-player-pivot;
        Table "public.tournament-player-pivot"
    Column    | Type | Collation | Nullable | Default 
--------------+------+-----------+----------+---------
 id           | uuid |           | not null | 
 tournamentID | uuid |           | not null | 
 playerID     | uuid |           | not null | 
Indexes:
    "tournament-player-pivot_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "tournament-player-pivot_playerID_fkey" FOREIGN KEY ("playerID") REFERENCES users(id)
    "tournament-player-pivot_tournamentID_fkey" FOREIGN KEY ("tournamentID") REFERENCES tournament(id)

在锦标赛中,它是这样定义的:

    @Siblings(
      through: TournamentPlayerPivot.self,
      from: \.$tournament,
      to: \.$player)
    var tournamentPlayers: [User]

反之,在用户中是:

    @Siblings(
      through: TournamentPlayerPivot.self,
      from: \.$player,
      to: \.$tournament)
    var playerTournaments: [Tournament]

所有这些似乎都非常严格地遵循标准做法。但是当调用上面的方法时(所有其他代码都按预期执行),table.

中没有条目

编辑:我省略了枢轴的 class:这里是:

import Foundation
import Fluent

final class TournamentPlayerPivot: Model {
    static let schema = "tournament-player-pivot"

    @ID
    var id: UUID?
    @Parent(key: "tournamentID")        var tournament: Tournament
    @Parent(key: "playerID")              var player: User

    init() {}

    init(
        id: UUID? = nil,
        tournament: Tournament,
        player: User
        ) throws {
            self.id = id
            self.$tournament.id = try tournament.requireID()
            self.$player.id = try player.requireID()
        }
}

这两个更新和附件可能有冲突。我会尝试将您的代码重新构建为:

func acceptInvitation(req: Request) -> EventLoopFuture<Response> {
    let user : User = req.auth.get(User.self)!
    let uId : UUID = user.id!
    let iId = UUID.init(uuidString: req.parameters.get("iId")!)
    return Invitation.query(on: req.db)
        .filter(\.$id == iId!)
        .with(\.$owner)
        .first().flatMap { i -> EventLoopFuture<Response> in
            i?.acceptances!.append((uId))
            i?.update(on: req.db).flatMap { _ in
                i!.owner.acceptances!.append(uId)
                i?.owner.update(on: req.db).flatMap { _ in
                    i?.owner.$tournamentPlayers.attach(user, on: req.db).flatMap { _ in
                        return req.eventLoop.future(req.redirect(to: "/")).encodeResponse(for: req)
                    }
                }
            }
        }
}

我确实在多次更新的上下文中看到了 missing/unchanged 数据,其中您没有映射未来的结果,并且 'wait' 更早的更新发生了。我的猜测是附加发生了类似的事情。您可能会遇到一些编译器问题,需要插入显式 return 类型。

@Nick:是的,基本上就是这样。我遇到了一个与列命名相关的错误,但这是到达数据库获取消息点的代码:

func acceptInvitation(req: Request) -> EventLoopFuture<Response> {
        let user : User = req.auth.get(User.self)!
        let uId : UUID = user.id!
        let iId = UUID.init(uuidString: req.parameters.get("iId")!)
        return Invitation.query(on: req.db)
            .filter(\.$id == iId!)
            .with(\.$owner)
            .first().flatMap { i -> EventLoopFuture<Response> in
                i?.acceptances!.append((uId))
                return (i?.update(on: req.db).flatMap { _ -> EventLoopFuture<Response> in
                    i!.owner.acceptances!.append(uId)
                    return (i?.owner.update(on: req.db).flatMap {
                        (i?.owner.$tournamentPlayers.attach(user, on: req.db).flatMap { _ in
                            return req.eventLoop.future(req.redirect(to: "/")).encodeResponse(for: req)
                        })!
                    })!
                })!
                
            }
    }

所以,主要是 return 和明确设置 return 值,以及嵌套、嵌套、嵌套。

感谢您的输入。