如何在 Vapor 4/FluentKit 中以一对多关系更新孩子?

问题描述

我已经梳理了文档 here,但我不太明白如何更新关系和模型(例如,关系发生了变化,属性发生了变化)。解码后,ModelA 中的“childrenArray”似乎为空,但是,我无法确定,因为在尝试打印值时出现此错误

致命错误:子关系未预先加载,使用 $ 前缀访问

我的父模型:

final class ModelA: Model,Content {
    static let schema = "model_a"
    
    // MARK: - PROPERTIES
    
    @ID(key: .id)
    var id: UUID?

    @Field(key: "name")
    var name: String
    
    // MARK: - RELATIONS
    
    @Children(for: \.$modelA)
    var childrenArray: [ModelB]

    init() { }

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

儿童模型:

final class ModelB: Model,Content {
    static let schema = "model_b"

    // MARK: - Properties
    
    @ID(key: .id)
    var id: UUID?

    @Field(key: "command")
    var command: String
    
    // MARK: - Relations
    
    @Parent(key: "model_a_id")
    var modelA: ModelA
}

我的更新功能

func update(req: Request) throws -> EventLoopFuture<ModelA> {
        guard let id = req.parameters.get("id",as: UUID.self) else {
            throw Abort(.internalServerError)
        }
        
        let updatedModelA = try req.content.decode(ModelA.self)
        return ModelA.find(id,on: req.db)
            .unwrap(or: Abort(.notFound))
            .flatMap { modelA in
                modelA.$childrenArray.create(updatedModelA.childrenArray,on: req.db)
                return modelA.update(on: req.db).map { modelA }
            }
    }

作为参考,Postman POST 请求如下所示:

{
    "id": "<ModelA's UUID>","name": "ModelA Name","childrenArray": [{
        "id": "{{$randomUUID}}","command": ""
    }]
}

解决方法

要完成“急切加载”,您需要在父查询中包含 true false false true false true 。您不能使用 with 执行此操作,因此您需要将查询更改为:

find

我假设您希望此行在 ModelB 中创建子项:

ModelA.query(on: req.db)
    .filter(\.$id == id)
    .with(\.$childrenArray)
    .first()
    .unwrap(or: Abort(.notFound))
    .flatMap { modelA in
        // can access children now
        return modelA.update(on: req.db).map { modelA }
    }

不会。您需要创建 modelA.$childrenArray.create(updatedModelA.childrenArray,on: req.db) 的新实例,初始化父属性,然后调用 ModelB

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...