Hey team! I'm wondering how to make queries with o...
# help
j
Hey team! I'm wondering how to make queries with one to many relationships. My specific example is an invoicing app where each
Invoice
has many
LineItems
. My db model is setup where the
LineItem
has a reference as
invoiceId
to the primary key of the corresponding invoice. I'm wondering how can query and create invoices that includes that line items themselves? The only thing I found in the docs is to include the foreign key relationship which I already have setup. So, I know I can query an invoice from a line item, but how do I query line items from an invoice?
n
Hello @James Q Quick! This thread has been automatically created from your message in #843999948717555735 a few seconds ago. We have already mentioned the @User so that they can see your message and help you as soon as possible! Want to unsubscribe from this thread? Right-click the thread in Discord (or use the ``...`` menu) and select "Leave Thread" to unsubscribe from future updates. Want to change the title? Use the ``/title`` command! We have solved your problem? Click the button below to archive it.
g
I think what you are looking for is this:
Copy code
.from('messages')
        .select('*, test!inner(*)')
        .eq('test.message_id',7)
Where 7 is the message id and test is a table with an fk to messages table. It returns: image
j
That does seem like what I'm looking for. Can you help me understand the syntax there? Is
test!inner(*)
saying to grab all items and call them an array called
test
then the selector is in the
eq
line specifying which items we want to get it?
g
Sorry, test is a table that has fk's pointing to messages that I quickly made to make sure I got the right syntax.
So I'm getting all the test items for this id in messages along with all my messages columns. I think that is what you are looking for where messages is Invoice and test is LineItems
j
Do you know how
eq
works specifically with a dynamic parameter. Like if I'm querying for an array of Invoices and their associated LineItems? I tried doing
Copy code
.eq(`LineItem.invoiceId`, `Invoice.id`);
but I'm getting a new error
Copy code
invalid input syntax for type bigint: "Invoice.id"'
g
Why are you passing a string in?
j
I'm not sure how to reference the id of the dynamically retrieved invoices. In your example, you have it hard coded to 7, but I'd like to tie it back to the dynamic invoices that I'm querying
g
You would pass in the invoice id with a variable
Is Invoice an object and id the int val key of your invoice? If then just use Invoice.id.
j
It's not a variable yet unfortunately. Like I'm not just querying for line items with a specific invoice. I'm querying all invoices AND their associated line items
g
Ah, totally different
j
So here's an example with the hard coded Invoice id I have so far.
Copy code
const { data: loadedInvoices, error: invoicesError } = await supabase
      .from('Invoice')
      .select(
        `
          id, status, subject, dueDate, issueDate, 
          discount, notes, amount,
          client:clientId (id, name, email, address, city, state, zip, phone),
          user:userId (id, name, email, address, city, state, zip, phone),
          LineItem!inner(*)
        `
      ).eq(`LineItem.invoiceId`, 51);
g
I thought you were wanting AN invoice with all the line times for it in your call.
j
ah yeah. This would be all invoices and their associated lineItems. I'm thinking it would be something close to what we have right now.
g
Not so sure from the client as you don't have the invoice ids and don't want to get and loop thru them client side.
j
Yeah right now, I have two separate queries and then merging the data together, but i feel like there's got to be a better way
g
For sure using an rpc and postgres function. Maybe a view also. I'm skeptical the PostgREST API the client uses though can generate the proper request, but I'm not a guru on it.
Try without the .eq at all and see what happens.
j
I think I got it.
Copy code
const { data: loadedInvoices, error: invoicesError } = await supabase
      .from('Invoice')
      .select(
        `
          id, status, subject, dueDate, issueDate, 
          discount, notes, amount,
          client:clientId (id, name, email, address, city, state, zip, phone),
          user:userId (id, name, email, address, city, state, zip, phone),
          LineItem: lineItems
        `
      );
g
LOL
j
It automatically is associating the line items appropriately because of the relationship!!
YAYYYY 🙂 lol
g
Sorry, for anyone scanning this later, we both posted the without .eq at sametime....
j
Somehow I just broke it lol
g
NOOOOO!
j
Wait yeah I lied. It hadn't worked before lol
Copy code
LineItem!inner(*): lineItems
g
j
That got me back to where I want it to be lol. Only thing is the naming. THe property in the returned value is
LineItem
instead of
lineItems
Thank you for the help @garyaustin !!