Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[improvement] @Relations.toMany & findOptions from Frontend #428

Open
jycouet opened this issue May 2, 2024 · 1 comment
Open

[improvement] @Relations.toMany & findOptions from Frontend #428

jycouet opened this issue May 2, 2024 · 1 comment

Comments

@jycouet
Copy link
Collaborator

jycouet commented May 2, 2024

Let's say that we have a Category entity with a tasksCompleted field.
I do:

@Relations.toMany<Category, Task>(() => Task, {
  // With findOptions, on the frontend, it's 1 query per line.
  findOptions: { where: { completed: true } },

  // Without findOptions, on the frontend, it's 1 query for the table (category.in[...])
})
tasksCompleted?: Task[]

I realized that findOptions can have a significant impact.

Here is the repro to play with this and look at the network tab.


What about supporting something like category.in[ {id: '', completed: true}, ... ] to have everything in one go?
FYI, it's not a top priority for me ✌️

@noam-honig
Copy link
Collaborator

It a bit more complex than I thought, as currently the query aggregation only works for in statement.

Here's the test for when we'll get to it

describe('test one to many relation load', () => {
  let remult = new Remult(new InMemoryDataProvider())

  @Entity('category')
  class category {
    @Fields.number()
    id: number = 0
    @Relations.toMany(() => task, 'categoryId')
    tasks?: task[]
  }
  @Entity('tasks')
  class task {
    @Fields.number()
    id = 0
    @Fields.boolean()
    completed = false
    @Fields.integer()
    categoryId = 0
  }
  let fetches: any[]
  beforeEach(async () => {
    remult = new Remult(new InMemoryDataProvider())
    await remult.repo(category).insert([{ id: 1 }, { id: 2 }])
    await remult.repo(task).insert([
      { id: 1, categoryId: 1 },
      { id: 2, categoryId: 2 },
    ])
    const mem = remult.dataProvider
    fetches = []
    remult.dataProvider = {
      transaction: undefined,
      getEntityDataProvider: (e) => {
        let r = mem.getEntityDataProvider(e)
        return {
          find: (x) => {
            fetches.push({ e: e.key, where: x.where.toJson() })
            return r.find(x)
          },
          count: (...args) => r.count(...args),
          delete: (...args) => r.delete(...args),
          insert: (...args) => r.insert(...args),
          update: (...args) => r.update(...args),
        }
      },
    }
  })
  it('test it', async () => {
    let c = await remult
      .repo(category)
      .find({ where: {}, include: { tasks: {} } })
    expect(fetches).toMatchInlineSnapshot(`
      [
        {
          "e": "category",
          "where": {},
        },
        {
          "e": "tasks",
          "where": {
            "categoryId.in": [
              1,
              2,
            ],
          },
        },
      ]
    `)
  })
  it.only('test it2', async () => {
    let c = await remult
      .repo(category)
      .find({ where: {}, include: { tasks: { where: { completed: true } } } })
    expect(fetches).toMatchInlineSnapshot(`
      [
        {
          "e": "category",
          "where": {},
        },
        {
          "e": "tasks",
          "where": {
            "categoryId.in": [
              1,
              2,
            ],
          },
        },
      ]
    `)
  })
})

Let's see how many votes this issue will get and take it from there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants