I was wondering how to create many-to-many relations in Vapor 3 using Fluent and FluentMySQL as described in the Vapor 2 docs
Sadly, the docs for Vapor 3 have not been updated yet and the implementation for the Pivot
protocol has changed.
Here is what I'm trying to do: I have two classes, User
and Community
. A Community
has members
and User
s can be members of multiple Community
s.
Currently, my code looks like this:
import Vapor
import FluentMySQL
final class Community: MySQLModel {
var id: Int?
//Community Attributes here
}
final class User: MySQLModel {
var id: Int?
//User Attributes here
}
extension Community {
var members: Siblings<Community, User, Pivot<Community, User>> {
return siblings()
}
}
However, this causes the following compiler errors:
Cannot specialize non-generic type 'Pivot'
and Using 'Pivot' as a concrete type conforming to protocol 'Pivot' is not supported
.
I have seen that there is a protocol extension called ModifiablePivot
but I don't know how to use it since there is no documentation or sample code anywhere.
Any help is appreciated. Thanks in advance!
Fluent 3 no longer provides a default pivot like Pivot
in Fluent 2. What you should do instead is create a type that conforms to Pivot
. There are some helper types in FluentMySQL
for this.
final class CommunityUser: MySQLPivot {
// implement the rest of the protocol requirements
var communityID: Community.ID
var userID: User.ID
}
Then use the CommunityUser
in place of Pivot<Community, User>
.
I had the same issue and both of the answers weren't sufficient for me, so i'm just posting my solution which worked for me.
// in CommunityUser.swift
import Vapor
import FluentMySQL
final class CommunityUser: MySQLPivot {
typealias Left = User
typealias Right = Community
static var leftIDKey: LeftIDKey = \.userID
static var rightIDKey: RightIDKey = \.communityID
var id: Int?
var userID: Int
var communityID: Int
init(id: Int?, userID: Int, communityID: Int) {
self.id = id
self.userID = userID
self.communityID = communityID
}
}
// CommunityUser didn't conform to MySQLMigration
// This simple line solves the problem
extension CommunityUser: MySQLMigration { }
For me CommunityUser
also needed to be migrated in the Database.
// in configure.swift
migrations.add(model: CommunityUser.self, database: .mysql)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With