Christian Louria
Christian Louria

Reputation: 31

Is it possible to return Fluent children in a GET request?

Right now I have the following two classes:

final class Song: MySQLModel {
    var id: Int?
    var lyrics: String
    var artist: String
    var title: String
    var strummingPattern: String

    init(id: Int? = nil, title: String, lyrics: String, artist: String, strummingPattern: String) {

        self.id = id
        self.lyrics = lyrics
        self.title = title
        self.artist = artist
        self.strummingPattern = strummingPattern

    }
}

extension Song {
    var chords: Children<Song, SongChord>{
        return children(\.songID)
    }
}

final class SongChord: MySQLModel {
    var id: Int?
    var songID: Int
    var chord: String
    var position: Int

    init(id: Int? = nil, chord: String, position: Int, songID: Int) {
        self.songID = songID
        self.id = id
        self.chord = chord
        self.position = position
    }
}

extension SongChord {
    var chords: Parent<SongChord, Song>{
        return parent(\.songID)
    }
}

I want to return a list of all Songs with their respective SongChord children. So far I've come up with:

return Song.query(on: req)
            .join(\SongChord.songID, to: \Song.id)
            .alsoDecode(SongChord.self)
            .all()

But this returns an error of "Cannot convert value of type 'EventLoopFuture<[(Song, SongChord)]>' to closure result type '_'". Some people online were suggesting doing a flatmap, but this was still producing an error. Any suggestions on how to retrieve the children would be appreciated.

Upvotes: 3

Views: 139

Answers (1)

cweinberger
cweinberger

Reputation: 3588

As the error implies you return EventLoopFuture<[(Song, SongChord)]>. If you decode multiple models from your query result, you will receive a Tupel of Song and SongChord for each result row; what you have to do now is:

  1. Create a struct (e.g. SongViewModel) that conforms to Content and has all relevant fields from Song and another var called chords: [SongChords]. Reason is, the original Song model has no array of SongChord but only a Children<Song, SongChord> which you cannot resolve easily
  2. Map your result from [(Song, SongChord)] to [SongViewModel]. This might be of help for you to transform your Tuple array: https://stackoverflow.com/a/31220067/710350
  3. return [SongViewModel]

Upvotes: 1

Related Questions