问题描述
我在如何通过包含额外字段的数据透视表返回包含多对多关系的模型方面苦苦挣扎。基本上,我想返回包含额外字段的完整数据透视表,但我不知道如何执行此操作。
让我们考虑以下 3 个模型:@StateObject var notificationmanager = Localnotificationmanager()
、Course
以及它们之间的支点 User
。 Student
模型包含额外的字段 Student
。
progress
我有一条这样的路线,它返回一系列课程:
final class Course: Model,Content {
static let schema = "courses"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
init() { }
}
final class Student: Model {
static let schema = "students"
@ID(key: .id)
var id: UUID?
@Parent(key: "course_id")
var course: Course
@Parent(key: "user_id")
var user: User
@Field(key: "progress")
var progress: Int
init() { }
}
final class User: Model,Content {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Field(key: "private")
var somePrivateField: String
init() { }
}
生成的 JSON 如下所示:
func list(req: Request) throws -> EventLoopFuture<[Course]> {
return Course
.query(on: req.db)
.all()
.get()
}
我怎样才能包括学生的数组,以便最终结果是这样的?
[
{
"id": 1,"name": "Course 1"
}
]
我可以像这样将用户添加到 [
{
"id": 1,"name": "Course 1","students": [
{
"user": {
"id": 1,"name": "User 1"
},"progress": 0
},{
"user": {
"id": 2,"name": "User 2"
},"progress": 100
},]
]
模型:
Course
然后像这样改变我的路线:
@Siblings(through: Student.self,from: \.$course,to: \.$user)
public var users: [User]
但这只会将用户信息添加到结果中,而不是数据透视表上的额外属性(即 func list(req: Request) throws -> EventLoopFuture<[Course]> {
return Course
.query(on: req.db)
.with(\.$user)
.all()
.get()
}
)。在我看来,即使数据透视表可以具有额外的属性并且文档甚至特别指出这一点,但没有实际处理这种情况的好方法,因为 progress
根本不指向数据透视表。
额外问题:我希望将 @Siblings
模型映射到 User
模型,以便私有/内部字段不是 JSON 结果的一部分。请参阅 this question 了解我的意思。我想做同样的事情,但使用 Student 枢纽的 User 模型。复杂,我知道?
解决方法
我在访问数据透视表中的其他字段时遇到了同样的问题,但有一种相当整洁的方法可以实现这一点。除了您的兄弟关系之外,还定义一个从 @Children
到 Course
的 Student
关系。然后,在您的查询中,执行嵌套的 with
。
将其放入您的课程模型中:
@Children(for:\.$course) var students: [Student]
查询:
let query = Course.query(on: req.db).with(\.$students){ $0.with(\.$user) }.all()
第一个 with
获取数据透视表的附加字段,然后嵌套的 with
获取 User
模型。