I have a one to many relation between i.e. Product...
# orm-help
k
I have a one to many relation between i.e. Product and Store. I can already create new Products that refer to their one Store like this: `` return await ctx.prisma.product.create({ data: { ..._data, // establish connection with store store_productTostore: { connect: { store_id }, }, }, }); ``
data
contains the input for the new
product
I checked the table it indeed refers to the designated home. However, I can't get the
products
column in Home to refer to the set of keys it has
products
is an array of the same type of key.id. I tried changing the above to this but it doesn't work: `` return await ctx.prisma.store.update({ where: { store_id }, data: { products: { create: { ...data } } } }); ``
n
Hey @KJReactor, I'd love to help you with this. Do you mind sharing the relevant parts of your data model? Also, have you already seen the docs here?
k
Hello @nikolasburk! Yes, I read the page you mentioned.
the models in question:
Copy code
model store {
  store_id Int       @default(autoincrement()) @id
  name     String    @unique
  url      String?   @unique
  products  product[]
}

model product {
  product_id           String            @id @default(cuid())
  name                 String            @unique
  description          String
  date                 DateTime          @default(dbgenerated())
  dateUpdated          DateTime?
  cost                 Float
  weight               Float
  height               Float
  width                Float
  rating               Float             @default(0)
  store                Int
  store_productTostore store             @relation(fields: [store], references: [store_id])
  feedback             feedback[]
  productCategory      productCategory[]
}
n
Ah thanks! Would you mind also specifying a bit further what exactly you meant with this:
However, I can't get the 
products
 column in Home to refer to the set of keys it has 
products
 is an array of the same type of key.id.
A few notes/questions I have about this statement: • there is no
products
column in the database.
products
is a relation field that only exists in the Prisma schema but not in the DB. • what do you mean with "in Home" exactly?
k
that is a typo. by Home I meant Store
and keys is Products
In the Store model there is a products field
set to an array of products
n
Sorry, I have a hard time following. Could you formulate once more what exactly you're trying to achieve?
k
I am trying to set a 1-to-many not 1-1. I manually set this up in the database myself. Up to that point, everything is fine. However, when a new product is created I need to add its
product_id
to the
products
field for the designated store
n
Does this help maybe?
Copy code
const newProduct = await prisma.product.create({
  data: {
    ...data,
    store_productTostore: {
      connect: {
        store_id: 42
      }
    }
  }
})
Ah I guess that's what you already tried... so what's the problem with this call?
After you did that, the new product should be part of the
products
array on the respective store.
k
Yes, I tried that
that's the problem, the
store
model / table is not updated
I had changed the above to this but also does not work:
Copy code
return ctx.prisma.store.update({
      where: { store_id },
      data: {
        products: {
          create: { ...data },
        },
      },
    });
n
Hmm, so the
store
table can't be updated because the table itself doesn't have a reference to the the
product
table.e
k
and error about the
products
argument being unknown
exactly!
I assume I would have to set the
products
column in store to a foreign key but I'm confused how since its an array. I tried doing it like any other foreign key. It didn't work
n
Ok, this code works for me:
Copy code
const newStore = await prisma.store.create({
    data: {
      name: "Bathing store",
    },
  });

  const data = {
    name: "BubbleBath",
    description: "asd",
    cost: 0,
    weight: 0,
    height: 0,
    width: 0,
  };

  const newProduct = await prisma.product.create({
    data: {
      ...data,
      store_productTostore: {
        connect: {
          store_id: newStore.store_id,
        },
      },
    },
  });


  const storeWithProducts = await prisma.store.findMany({
    include: {
      products: true
    }
  })
  console.dir(storeWithProducts, { depth: null})
Ok, so I think you have a confusion about how relations are modeled in the underlying database. For 1-n relations, you only have a foreign key on one side of the relation. Maybe this section in the docs helps you better understand the concepts that are at play here 🙂
👍 1
k
Thanks but I know how it works. However, I tried this several times and after viewing the examples, I noticed an array being used on the many side. I knew it was weird but I assumed it had something to do with how Prisma works
anyways, I'll show you where it was mentioned..one min
in the model example immediately under "one-to-many relations"
notice the array used for the
posts
field for the
user
model
😀 I misinterpreted the model..."*The
posts
field does not "manifest" in the underlying database schema*".
n
in the model example immediately under "one-to-many relations"
Ah thanks for pointing this out! This is actually an error in the docs, you can't define the models like this:
Copy code
model User {
  id       Int     @id @default(autoincrement())
  email    String  @unique
  posts    Post[]
}
model Post {
  id         Int      @id @default(autoincrement())
  title      String
  published  Boolean  @default(false)
  author     User?
}
This is missing the relation scalar field, here's what it should look like:
Copy code
model User {
  id        Int      @id @default(autoincrement())
  email    String  @unique
  posts     Post[]
}
model Post {
  id        Int   @id @default(autoincrement())
  title      String
  published  Boolean  @default(false)
  author    User  @relation(fields: [authorId], references: [id])
  authorId  Int
}
k
Thanks @nikolasburk
👍 1
@nikolasburk, hey sorry but to I can select
products
on the
Store
is as follows, correct?
Copy code
return await ctx.prisma.store.findOne({
      where,
      include: {
        product: true,
      },
    });
n
I guess it should be
product*s*: true
and not
product: true
, but otherwise this looks right to me 👍
Does that help? 🙂
k
neither works
I keep getting error: "column product.store" does not exists
error occurs only when I use the "include:{..."
Copy code
model product {
  product_id           String            @id @default(cuid())
  name                 String            @unique
  description          String
  date                 DateTime          @default(dbgenerated())
  dateUpdated          DateTime?
  cost                 Float
  weight               Float
  height               Float
  width                Float
  rating               Float             @default(0)
  store_id             Int
  store_productTostore store             @relation(fields: [store_id], references: [store_id])
  feedback             feedback[]
  productCategory      productCategory[]
}

model store {
  store_id Int       @default(autoincrement()) @id
  name     String    @unique
  url      String?   @unique
  products  product[]
}
Copy code
return await ctx.prisma.store.findOne({
      where,
      include: {
        products: true,
      },
    });
n
Hmm, just to confirm, you're using JavaScript and not TypeScript, right?
k
correct
n
Are using Prisma Migrate (i.e. did you run
prisma migrate save
and
prisma migrate up
) or introspection?
k
i changed db manually. introspect
but I forgot to do so just now 😂
😅 1
I just did, the schema remains the same so the above still stands
n
Can you share the SQL for the
store
and
product
tables as well? Also make sure to re-run
prisma generate
after any changes to the DB and Prisma schema.
k
Yes.
Copy code
create table "product"(
  "product_id" varchar(30) not null primary key,
  "name" varchar(25) not null unique,
  "description" text not null,
  "date" date not null default current_date,
  "dateUpdated" date,
  "cost" float not null,
  "weight" float not null,
  "height" float not null,
  "width" float not null,
  "rating" float not null default 0,
  "store_id" int not null,
  foreign key ("store_id") references "store"("store_id")
);

create table "store"(
  "store_id" serial primary key,
  "name" varchar(25) not null unique,
  "url" varchar(30) unique
);
I have it regenerated automatically upon changes
n
Quick side-question: Is it intentional that you're using a
String
ID for the
product
table but autoincrementing integers for
store
? Any reason why
product
shouldn't have the same ID type?
k
yes, intentional
n
Ah, just realized that you added the
@default(cuid())
manually to the schema, that makes sense 👍
k
Yes 🙂 you had me second guessing myself there for a sec
n
Hmm, I can't reproduce the error 🤔 This code seems is working for me:
Copy code
const store = await prisma.store.create({
  data: {
      name: 'MyShop3'
  }
})

const product = await prisma.product.create({
   data: {
    cost: 0,
    description: "A cool product",
    name: "myProduct3",
    weight: 0,
    height: 0,
    width: 0,
    store: {
      connect: {
         store_id: store.store_id
      }
    }
  }
})

const findStore = await prisma.store.findOne({
  where: { store_id: store.store_id },
  include: {
    products: true
  },
});

console.dir(findStore, { depth: null})
It logs:
Copy code
{
  store_id: 4,
  name: 'MyShop3',
  url: null,
  products: [
    {
      product_id: 'ckebfvot60000xecbi27o3p8t',
      name: 'myProduct3',
      description: 'A cool product',
      date: 2020-08-26T00:00:00.000Z,
      dateUpdated: null,
      cost: 0,
      weight: 0,
      height: 0,
      width: 0,
      rating: 0,
      store_id: 4
    }
  ]
}
If the problem persists for you, can you please create an issue with as much context as possible for your error 🙂
k
ok
can I view the models you used if any?
n
What do you mean with typedefs exactly? I didn't build a GraphQL server with this (if that's what you meant) but just reproduced your issue in an isolated environment 🙂
k
I meant models
n
Ah sorry 😅
Copy code
model product {
  product_id  String    @id @default(cuid())
  name        String    @unique
  description String
  date        DateTime  @default(dbgenerated())
  dateUpdated DateTime?
  cost        Float
  weight      Float
  height      Float
  width       Float
  rating      Float     @default(0)
  store_id    Int
  store       store     @relation(fields: [store_id], references: [store_id])
}

model store {
  store_id Int       @default(autoincrement()) @id
  name     String    @unique
  url      String?   @unique
  products product[]
}
k
thanks