5

所以我有模型名称Organization,UserApp. 应用程序和用户都属于组织。

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'

我应该怎么做?

4

2 回答 2

11

您需要提供要过滤的属性包装器的预计值的关键路径,而不是值本身。因此,正如您发现的那样:

.filter(\.$organization.$id == user.$organization.id)

您必须使用属性包装器的投影值而不是仅使用属性本身的原因是因为属性包装器包含执行查询所需的信息(如列名),而这些信息仅适用于属性

于 2020-08-05T23:03:32.593 回答
2

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()

我不完全知道它为什么起作用,但这是反斜杠和美元符号的正确组合。

于 2020-08-03T19:57:01.623 回答