Just started with Vapor 3 along with a MySQL database and I am having hard time figuring out the Relations part.
I have created 2 models so far: Movie
and Actor
.
A Movie
can have many Actor
s and an Actor
can have many Movie
s.
Movie
Model:
import Vapor
import FluentMySQL
final class Movie: Codable {
var id: Int?
var name: String
var synopsis: String
var dateReleased: Date
var totalGrossed: Float
init(id: Int? = nil, name: String, synopsis: String, dateReleased: Date, totalGrossed: Float) {
self.id = id
self.name = name
self.synopsis = synopsis
self.dateReleased = dateReleased
self.totalGrossed = totalGrossed
}
}
extension Movie {
var actors: Siblings<Movie, Actor, MovieActor> {
return siblings()
}
}
extension Movie: Content {}
extension Movie: Parameter {}
extension Movie: MySQLModel {}
extension Movie: MySQLMigration {
static func prepare(on conn: MySQLConnection) -> Future<Void> {
return MySQLDatabase.create(self, on: conn) { builder in
builder.field(for: \.id, isIdentifier: true)
builder.field(for: \.name)
builder.field(for: \.synopsis)
builder.field(for: \.dateReleased, type: .date)
builder.field(for: \.totalGrossed, type: .float)
}
}
}
Actor
Model:
import Vapor
import FluentMySQL
final class Actor: Codable {
var id: Int?
var firstName: String
var lastName: String
var fullName: String {
return firstName + " " + lastName
}
var dateOfBirth: Date
var story: String
init(id: Int? = nil, firstName: String, lastName: String, dateOfBirth: Date, story: String) {
self.id = id
self.firstName = firstName
self.lastName = lastName
self.dateOfBirth = dateOfBirth
self.story = story
}
}
extension Actor {
var actors: Siblings<Actor, Movie, MovieActor> {
return siblings()
}
}
extension Actor: Content {}
extension Actor: Parameter {}
extension Actor: MySQLModel {}
extension Actor: MySQLMigration {
static func prepare(on conn: MySQLConnection) -> Future<Void> {
return MySQLDatabase.create(self, on: conn) { builder in
builder.field(for: \.id, isIdentifier: true)
builder.field(for: \.firstName)
builder.field(for: \.lastName)
builder.field(for: \.dateOfBirth, type: .date)
builder.field(for: \.story, type: .text)
}
}
}
And I have also created a MovieActor
model as a MySQLPivot
for the relationship:
import Vapor
import FluentMySQL
final class MovieActor: MySQLPivot {
typealias Left = Movie
typealias Right = Actor
static var leftIDKey: LeftIDKey = \.movieID
static var rightIDKey: RightIDKey = \.actorID
var id: Int?
var movieID: Int
var actorID: Int
init(movieID: Int, actorID: Int) {
self.movieID = movieID
self.actorID = actorID
}
}
extension MovieActor: MySQLMigration {}
And have added them to the migration section in the configure.swift file:
var migrations = MigrationConfig()
migrations.add(model: Movie.self, database: .mysql)
migrations.add(model: Actor.self, database: .mysql)
migrations.add(model: MovieActor.self, database: .mysql)
services.register(migrations)
All the tables in the database are being created just fine, but I am not receiving the relationship when calling the get all movies
service. I am just receiving the Movie
's properties:
final class MoviesController {
func all(request: Request) throws -> Future<[Movie]> {
return Movie.query(on: request).all()
}
}
[
{
"id": 1,
"dateReleased": "2017-11-20T00:00:00Z",
"totalGrossed": 0,
"name": "Star Wars: The Last Jedi",
"synopsis": "Someone with a lightsaber kills another person with a lightsaber"
},
{
"id": 3,
"dateReleased": "1970-07-20T00:00:00Z",
"totalGrossed": 0,
"name": "Star Wars: A New Hope",
"synopsis": "Someone new has been discovered by the force and he will kill the dark side with his awesome lightsaber and talking skills."
},
{
"id": 4,
"dateReleased": "2005-12-20T00:00:00Z",
"totalGrossed": 100000000,
"name": "Star Wars: Revenge of the Sith",
"synopsis": "Anakin Skywalker being sliced by Obi-Wan Kenobi in an epic dual of fates"
}
]
Your help would be appreciated! Thank you very much :)