databasefluentvaporvapor-fluentserver-side-swift

How to decide to use siblings or parent/children relations in vapor?


I have a table named posts, and users can add any post to his favorites. From the perspective of the post, this is User(Parent)/Post(children) relation. But a post can be added to any user's favorites, in this case, should I use the siblings relation?

Here is post Model:

final class Post: Model, Content {
    
    static let schema = "posts"
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: Keys.title)
    var title: String
    
    // one-to-many relationship...
    @Parent(key: Keys.author)
    var author: User
    
    // many-to-many relationship...
    //    @Siblings(through: PostFavoritesPivot.self, from: \.$post, to: \.$user)
    //    var users: [User]
 }

Here is User model:

final class User: Model, Content {
    
    static let schema = "users"
    
    @ID(key: .id)
    var id: UUID?
    
    // one-to-many relationship
    @Children(for: \.$author)
    var favorites: [Post]
    
    // many-to-many relationship
    // @Siblings(through: PostFavoritesPivot.self, from: \.$user, to: \.$post)
    // var favorites: [Post]
    
    // which relationship should i take?
}

Here is pivot Model if i choose siblings relations:

final class PostFavoritesPivot: Model {
    
    struct Keys {
        static let postId: FieldKey = "post_id"
        static let userId: FieldKey = "user_id"
    }
    
    static let schema = "post-favorites-pivot"
    
    @ID(key: .id)
    var id: UUID?
    
    @Parent(key: Keys.postId)
    var post: Post
    
    @Parent(key: Keys.userId)
    var user: User
}

And there are some similar questions, like thumbs-up to a post, follow some users...

I've been wondering for a long time, thanks in advance.


Solution

  • The type of relationship you use entirely depends on how you expect the models to be linked. In your case, a post can only be created by a single user and a user can create one or more posts, so that's a one-to-many or parent-child relationship.

    For liking a post, a user can like or more posts and a post can be liked by one or more users, so that's a many-to-many relationship or sibling relationship.

    Just because there's already an existing relationship between a user and a post (creating a post) doesn't mean you can't model different, additional relationships between the same models.