Vapor 4:如何包含兄弟姐妹,包括枢轴 table 的额外属性?
Vapor 4: how to include siblings including extra properties from the pivot table?
我在如何 return 通过包含额外字段的枢轴 table 包含多对多关系的模型方面苦苦挣扎。基本上,我想 return 具有额外字段的完整枢轴 table,但我不知道该怎么做。
让我们考虑以下 3 个模型: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() { }
}
我有一条这样的路线,其中 return 是一系列课程:
func list(req: Request) throws -> EventLoopFuture<[Course]> {
return Course
.query(on: req.db)
.all()
.get()
}
结果 JSON 看起来像这样:
[
{
"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()
}
但这只会将用户信息添加到结果中,而不是枢轴 table(即 progress
)上的额外属性。在我看来,即使 pivot tables 可以有额外的属性并且文档甚至特别指出了这一点,但实际上没有很好的方法来处理这种情况,因为 @Siblings
没有指向完全是枢轴。
附加问题:我希望将 User
模型映射到 PublicUser
模型,以便 private/internal 字段不是 JSON 结果的一部分。请参阅 了解我的意思。我想做同样的事情,但使用 Student pivot 的 User 模型。复杂,我知道
我在访问数据透视表 table 中的其他字段时遇到了相同的问题,但有一种相当简洁的方法可以完成此操作。除了你的兄弟姐妹关系,定义一个从 Course
到 Student
的 @Children
关系。然后,在您的查询中,执行嵌套 with
.
将其放入您的课程模型中:
@Children(for:\.$course) var students: [Student]
查询:
let query = Course.query(on: req.db).with(\.$students){ [=11=].with(\.$user) }.all()
第一个 with
获取主元的附加字段 table,然后嵌套 with
获取 User
模型。
您可以直接使用 Sibling
关系上的 pivots
属性 查询和使用枢轴 table 上的额外属性,该关系急切地加载枢轴 table 对象通过兄弟关系方便访问。
例如:
Course.query(on: db)
.with(\.$user)
.with(\.$user.$pivots).all().map { course in
// you can now access the loaded students using:
let students = course.$user.pivots
...
}
我在如何 return 通过包含额外字段的枢轴 table 包含多对多关系的模型方面苦苦挣扎。基本上,我想 return 具有额外字段的完整枢轴 table,但我不知道该怎么做。
让我们考虑以下 3 个模型: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() { }
}
我有一条这样的路线,其中 return 是一系列课程:
func list(req: Request) throws -> EventLoopFuture<[Course]> {
return Course
.query(on: req.db)
.all()
.get()
}
结果 JSON 看起来像这样:
[
{
"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()
}
但这只会将用户信息添加到结果中,而不是枢轴 table(即 progress
)上的额外属性。在我看来,即使 pivot tables 可以有额外的属性并且文档甚至特别指出了这一点,但实际上没有很好的方法来处理这种情况,因为 @Siblings
没有指向完全是枢轴。
附加问题:我希望将 User
模型映射到 PublicUser
模型,以便 private/internal 字段不是 JSON 结果的一部分。请参阅
我在访问数据透视表 table 中的其他字段时遇到了相同的问题,但有一种相当简洁的方法可以完成此操作。除了你的兄弟姐妹关系,定义一个从 Course
到 Student
的 @Children
关系。然后,在您的查询中,执行嵌套 with
.
将其放入您的课程模型中:
@Children(for:\.$course) var students: [Student]
查询:
let query = Course.query(on: req.db).with(\.$students){ [=11=].with(\.$user) }.all()
第一个 with
获取主元的附加字段 table,然后嵌套 with
获取 User
模型。
您可以直接使用 Sibling
关系上的 pivots
属性 查询和使用枢轴 table 上的额外属性,该关系急切地加载枢轴 table 对象通过兄弟关系方便访问。
例如:
Course.query(on: db)
.with(\.$user)
.with(\.$user.$pivots).all().map { course in
// you can now access the loaded students using:
let students = course.$user.pivots
...
}