Как в Fluent / Vapor 4 отфильтровать список на основе внешнего ключа? - PullRequest
1 голос
/ 03 августа 2020

, поэтому у меня есть названия моделей 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'.

Что мне делать вместо этого?

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

Вам необходимо указать ключевой путь к прогнозируемому значению оболочки свойства, по которой вы хотите выполнить фильтрацию, вместо самого значения. Итак, если вы обнаружили, что это должно быть:

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

Причина, по которой вы должны использовать спроектированное значение оболочки свойства вместо самого свойства, заключается в том, что оболочка свойства содержит информацию, необходимую для выполнения запроса (например, имя столбца), который был бы недоступен только с помощью свойства

1 голос
/ 03 августа 2020

Пользователь jimmy#2207 из разногласий Vapor дал мне следующий ответ:

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

Я точно не знаю, почему это работает, но это правильная комбинация обратной косой черты и знаков доллара.

...