Riki
Riki7mo ago

Pagination and Self-Reference

Let's say two users can be friends. To model this, I used the following approach:
schema.ts

const users = defineTable({ ... })

const friendsRelationships = defineTable({
user1Id: v.id("users"),
user2Id: v.id("users")
schema.ts

const users = defineTable({ ... })

const friendsRelationships = defineTable({
user1Id: v.id("users"),
user2Id: v.id("users")
Then user1Id and user2Id can be populated by some user Ids. However, what if I want to retrieve all the friends of a given user that are paginated. Given a user id can either be in user1Id or user2Id it looks like this is not possible with the current approach. As an alternative, we could duplicate all the relationships and swap user1Id and user2Id so that I can paginate by indexing user1Id or user2Id, but this doesn't look optimal to duplicate those in the same table.
3 Replies
erquhart
erquhart7mo ago
I've come to adopt some patterns in Convex that "feel" wrong, but work just fine. If I had to implement this today, I'd probably use the duplication approach you mentioned. It is trivial to keep things synced in Convex, eg., ensuring both records are added deleted together, due to transactions. Moving from a "single source of truth" model to a "single point of access" model helps. The duplication approach creates two records to capture a single relationship, so you have two sources of truth, but if you ensure you only have one helper function translating those records for the rest of your application, you have one place to ensure things are in sync. Same for write/update/delete. This way, the fact each relationship has two records becomes a low level implementation detail. Your singular read/write/delete (and list/paginate) helper functions for the relationships table will deal with it, but to the rest of your app, including the convex query/mutation/action functions that use the helpers, you effectively have one record per relationship.
Michal Srb
Michal Srb7mo ago
https://labs.convex.dev/convex-ents use the duplicated approach for many:many relationships
Convex Ents - Convex Ents
Relations, default values, unique fields and more for Convex
Riki
RikiOP7mo ago
Sorry for the delay. That's clear and interesting. It means changing my approach: duplicating entities and creating CRUD operations when trying to update the "main" entities so it forward those changes, alright. Thanks for the help as always guys

Did you find this page helpful?