在 Fluent / Vapor 4 中,如何根据外键过滤列表?
In Fluent / Vapor 4, how do I filter a list based on a foreign key?
所以我有模型名称 Organization
、User
和 App
。应用程序和用户都属于组织。
final class Organization: Model, Content {
static let schema = "organizations"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Children(for: \.$organization)
var users: [User]
}
final class App: Model, Content {
static let schema = "apps"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Parent(key: "organization_id")
var organization: Organization
}
final class User: Model, Content {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "email")
var email: String
@Field(key: "password_hash")
var passwordHash: String
@Parent(key: "organization_id")
var organization: Organization
}
现在,基本上我想做的是,给定一个用户,我想获取属于该用户组织的所有应用程序。
我可以从我的身份验证系统中获取用户,但是我只有这个查询:
let user = try req.auth.require(User.self)
return App.query(on: req.db).filter(\.$organization.id == user.$organization.id).all()
失败并显示错误消息 Operator function '==' requires that 'UUID' conform to 'QueryableProperty'
。
我应该怎么做?
来自 Vapor discord 的用户 jimmy#2207
为我提供了这个答案:
let user = try req.auth.require(User.self)
// Only show user's orgs' apps, thanks to @jhoughjr
return App.query(on: req.db)
.filter(\.$organization.$id == user.$organization.id)
.all()
我不太清楚为什么会这样,但这是反斜杠和美元符号的正确组合。
您需要提供要过滤的 属性 包装器的预计值的关键路径,而不是值本身。所以正如您发现的那样:
.filter(\.$organization.$id == user.$organization.id)
您必须使用 属性 包装器的预计值而不仅仅是 属性 本身的原因是因为 属性 包装器包含执行查询所需的信息 (像列名),仅 属性
不可用
所以我有模型名称 Organization
、User
和 App
。应用程序和用户都属于组织。
final class Organization: Model, Content {
static let schema = "organizations"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Children(for: \.$organization)
var users: [User]
}
final class App: Model, Content {
static let schema = "apps"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Parent(key: "organization_id")
var organization: Organization
}
final class User: Model, Content {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "email")
var email: String
@Field(key: "password_hash")
var passwordHash: String
@Parent(key: "organization_id")
var organization: Organization
}
现在,基本上我想做的是,给定一个用户,我想获取属于该用户组织的所有应用程序。
我可以从我的身份验证系统中获取用户,但是我只有这个查询:
let user = try req.auth.require(User.self)
return App.query(on: req.db).filter(\.$organization.id == user.$organization.id).all()
失败并显示错误消息 Operator function '==' requires that 'UUID' conform to 'QueryableProperty'
。
我应该怎么做?
来自 Vapor discord 的用户 jimmy#2207
为我提供了这个答案:
let user = try req.auth.require(User.self)
// Only show user's orgs' apps, thanks to @jhoughjr
return App.query(on: req.db)
.filter(\.$organization.$id == user.$organization.id)
.all()
我不太清楚为什么会这样,但这是反斜杠和美元符号的正确组合。
您需要提供要过滤的 属性 包装器的预计值的关键路径,而不是值本身。所以正如您发现的那样:
.filter(\.$organization.$id == user.$organization.id)
您必须使用 属性 包装器的预计值而不仅仅是 属性 本身的原因是因为 属性 包装器包含执行查询所需的信息 (像列名),仅 属性
不可用