1

这可能是一个微不足道的问题,但我无法解决它,也没有找到答案。
我有 3 个相互关联的表作为父子和兄弟姐妹。我想从所有表和相同的 JSON 响应中返回一些值。

final class ClimbingGym: Model, Content {

    static let schema = "climbing_gyms"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "name")
    var name: String

    @Field(key: "description")
    var description: String

    @Siblings(through: ClimbingDisciplineClimbingGym.self, from: \.$gym, to: \.$discipline)
    var disciplines: [ClimbingDiscipline]

    @Children(for: \.$gym)
    var socialNetworks: [SocialNetwork]

    init() { }

    init(
        id: UUID? = nil,
        name: String,
        description: String,
    ) {
        self.id = id
        self.name = name
        self.description = description
    }
}

enum ClimbingDisciplineType: String, Codable, CaseIterable, Equatable {
    static let schema = "climbing_discipline_type"

    case lead
    case boulder
    case speed
}

final class ClimbingDiscipline: Model, Content {

    static let schema = "climbing_disciplines"

    @ID(key: .id)
    var id: UUID?

    @Enum(key: "type")
    var type: ClimbingDisciplineType

    init() { }

    init(
        id: UUID? = nil,
        type: ClimbingDisciplineType
    ) {
        self.id = id
        self.type = type
    }
}

final class SocialNetwork {
    static let schema = "social_networks"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "link")
    var link: String

    @Parent(key: "gym_id")
    var gym: ClimbingGym

    init() { }

    init(
        id: UUID? = nil,
        link: String,
        gym: ClimbingGym
    ) throws {
        self.id = id
        self.link = link
        self.$gym.id = try gym.requireID()
    }
}

我想返回那个模型:

struct ClimbingGymResponse: Codable, Content {
    let id: UUID
    let name: String
    let description: String
    let disciplines: [ClimbingDisciplineType]
    let socialNetworks: [String]
}

所以我现在使用的查询看起来像这样

func getAll(req: Request) throws -> EventLoopFuture<[ClimbingGymResponse]> {
   ClimbingGym
      .query(on: req.db)
      .join(children: \ClimbingGym.$socialNetworks)
      .join(siblings: \ClimbingGym.$disciplines)
      .all()    
}

它显然不起作用,因为它返回[ClimbingGym]而不是[ClimbingGymResponse].

那么我怎样才能将一个转换为另一个呢?
我在每个健身房的填充disciplines: [ClimbingDisciplineType]socialNetworks: [String]场地方面都有问题

谢谢!

4

1 回答 1

3

您可以将结果数组映射到所需的类型。所以

ClimbingGym
  .query(on: req.db)
  .with(\.$socialNetworks)
  .with(\.$disciplines)
  .all().flatMapThrowing { gyms in
    try gyms.map { try ClimbingGymResponse(id: $0.requireID(), ...) }
}
于 2020-12-13T01:19:46.000 回答