Skip to content

Instantly share code, notes, and snippets.

@acro5piano
Created March 16, 2021 09:13
Show Gist options
  • Save acro5piano/2e8b55de648d8b6512580284e0b13217 to your computer and use it in GitHub Desktop.
Save acro5piano/2e8b55de648d8b6512580284e0b13217 to your computer and use it in GitHub Desktop.
Many to many relationship + Dataloader

Assuming

users:
  - id 
  - name
post_user:
  - post_id
  - user_id
posts:
  - id
  - title

Using Knex query builder:

import Dataloader from 'dataloader'

const postsByUserId = new Dataloader((ids: readonly ID[]) => {
  const select = (userId: ID) =>
    this.database.knex
      .select('posts.*', 'user_id as userId')
      .from('posts')
      .innerJoin(
        'post_user',
        'post_user.user_id',
        'post_user.post_id',
      )
      .where('post_user.user_id', userid)
  
  const [initial, ...rest] = ids
  
  const union = rest.reduce(
    (built, userId) => built.unionAll(select(userId), true),
    select(initial),
  )
  
  return union.then((rows) =>
    ids.map((id) => rows.filter((x: any) => x.userId === id)),
  )
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment