triplit icon indicating copy to clipboard operation
triplit copied to clipboard

Child relations fail when only one related record exists

Open jakobrosenberg opened this issue 6 months ago • 3 comments

When using RelationMany with a where clause like [['branch_id', '=', '$id']], the relation works as expected if multiple related records exist. However, when only a single related record exists, it resolves to an empty array.

import { Schema as S, TriplitClient } from '@triplit/client'
import { createServer, createTriplitStorageProvider } from '@triplit/server'
import jwt from 'jsonwebtoken'

const jwtSecret = 'test'
const token = jwt.sign({ 'x-triplit-token-type': 'secret' }, jwtSecret)

const schema = S.Collections({
  branches: {
    schema: S.Schema({
      id: S.String(),
      branch_id: S.String({ nullable: true }),
    }),
    relationships: {
      branches: S.RelationMany('branches', { where: [['branch_id', '=', '$id']] }),
    },
  },
})

const client = new TriplitClient({ serverUrl: 'http://localhost:1235', token, schema })

beforeAll(async () => {
  const startServer = await createServer({
    storage: await createTriplitStorageProvider('memory'),
    jwtSecret,
    dbOptions: { schema: { collections: schema } },
  })
  startServer(1235)
})

beforeEach(() => client.http.deleteAll('branches'))

describe('Child relations', async () => {
  test('can see two child relations', async () => {
    await client.http.bulkInsert({
      branches: [
        { id: 'a', branch_id: null },
        { id: 'b', branch_id: 'a' },
        { id: 'c', branch_id: 'a' },
      ],
    })
    const result = await client.http.fetchOne(client.query('branches').Id('a').Include('branches'))
    expect(result.branches.length).toBe(2)
  })

  // BROKEN
  test('can see one child relation', async () => {
    await client.http.bulkInsert({
      branches: [
        { id: 'a', branch_id: null },
        { id: 'b', branch_id: 'a' },
        // { id: 'c', branch_id: 'a' }, // leaving only one child breaks child relations
      ],
    })
    const result = await client.http.fetchOne(client.query('branches').Id('a').Include('branches'))
    expect(result.branches.length).toBe(1) // should be 1, is 0
  })
})

jakobrosenberg avatar Jun 28 '25 15:06 jakobrosenberg

Can you confirm this is fixed with @triplit/client:1.0.45? Closing for now, but please re-open if not.

wernst avatar Jul 02 '25 00:07 wernst

@wernst I do not have permission to reopen, but I can confirm that the bug is still present.

jakobrosenberg avatar Jul 02 '25 06:07 jakobrosenberg

Taking a look, I put in a fix for the lower level DB, but there may be another edge case with the http client.

wernst avatar Jul 02 '25 17:07 wernst