In Prisma, how to specify 1-to-n relation where always n>0? - prisma

The Prisma data model of my app has Posts, and each Post has a number of Authors. They can't have zero authors. As I understand it, the following model:
model Post {
id Int #id #default(autoincrement())
title String
authors Author[] #relation(references: [id])
}
allows a Post to have zero Authors. I'm new to Prisma. Can my data model be changed to reflect that a Post needs at least one Author?

Related

Ambiguous self relation detected [duplicate]

I am trying to create a prisma schema for a self relation. I would like to be able to show related posts for each post. Here is my post model:
model Post {
id Int #id #default(autoincrement())
title String
content String
relatedPosts Post[]
}
I am unsure on how to get this to work, the error message I am getting says that I need to define the other side of the relationship.
You are trying to create a many-to-many self relation. In such cases, you need to create two fields:
One field to represent the suggested posts for a given parent post (named relatedPosts in the example)
One field to represent the parent for a given suggested post (named relatedPostParent in the example)
This is what the syntax will look like
model Post {
id Int #id #default(autoincrement())
title String
content String
relatedPosts Post[] #relation("RelatedPosts", references: [id]) // child post (post that are suggested)
relatedPostParent Post[] #relation("RelatedPosts", references: [id]) // parent post (parent post of a suggested post)
}
Note that this is an implicit many-to-many relation. The article linked at the top also shows how to create an explicit many-to-many relation, if that is what you'd prefer.

Prisma self relation to display related posts

I am trying to create a prisma schema for a self relation. I would like to be able to show related posts for each post. Here is my post model:
model Post {
id Int #id #default(autoincrement())
title String
content String
relatedPosts Post[]
}
I am unsure on how to get this to work, the error message I am getting says that I need to define the other side of the relationship.
You are trying to create a many-to-many self relation. In such cases, you need to create two fields:
One field to represent the suggested posts for a given parent post (named relatedPosts in the example)
One field to represent the parent for a given suggested post (named relatedPostParent in the example)
This is what the syntax will look like
model Post {
id Int #id #default(autoincrement())
title String
content String
relatedPosts Post[] #relation("RelatedPosts", references: [id]) // child post (post that are suggested)
relatedPostParent Post[] #relation("RelatedPosts", references: [id]) // parent post (parent post of a suggested post)
}
Note that this is an implicit many-to-many relation. The article linked at the top also shows how to create an explicit many-to-many relation, if that is what you'd prefer.

What is the correct way to name relations in Prisma? Are there guidelines or conventions I should follow?

I have a User model which can post Comments and vote on them. Comments can also be parented to each other (for nested comments like on HN or Reddit`).
model User {
[...]
// Comments the user has posted
comments Comment[] #relation("UserToComment")
// Comments the user has voted on
upvotedComments Comment[] #relation("_UpvoterToComment")
downvotedComments Comment[] #relation("_DownvoterToComment")
}
model Comment {
[...]
// Comment's author
author User #relation("UserToComment", fields: [authorId], references: [id])
authorId String
// Users who voted on the comment
upvoters User[] #relation("_UpvoterToComment")
downvoters User[] #relation("_DownvoterToComment")
// One-to-many self-relation for nested comments
parentId String?
parent Comment? #relation("Parent", fields: [parentId], references: [id])
children Comment[] #relation("Parent")
}
I have a few questions on how to correctly name these relations.
How should relation that describes the User being an author of several Comments be named:
"UserToComment"?
"Author"?
"CommentAuthor"?
"UserComments"?
I've read somewhere that many-to-many relation names are supposed to start with an underscore (but I'm not sure why, and whether this applies to one-to-many relations as well). How should the relation that describes the multiples Users being upvoters of multiple Comments be named:
"_UpvoterToComment"?
"UpvoterToComment"?
"UserUpvoted"?
"Upvoters"?
Finally, I have a Comment relating to itself for the nested comments. Should this relation be named:
"Parent"?
"Children"?
"ParentChildren"?
"CommentToComment"?
Any of the above but with the underscore in front?
Can you guys help me to understand the correct conventions here, give me some advice on how should name my relations?
General Advice on naming in prisma
Naming is a bit subjective. Normally, I think you should do what makes the most sense for you and your use-case. There are some conventions and rules that Prisma recommends, that you should follow as well:
Convention for model names
Convention for field names
However, there aren't any guidelines on naming relations.
Naming for the specific usecases mentioned
In general, go with whatever you think concisely describes the relationship itself. I can give you my personal opinion about the specific naming questions you brought up:
How should relation that describes the User being an author of several Comments be named:
I think UserComments make sense.
I've read somewhere that many-to-many relation names are supposed to start with an underscore.
This is something that Prisma does internally when automatically generating the underlying SQL. You don't have to worry about this at all, nor should you explicitly add a _ at the beginning of a name.
How should the relation that describes the multiples Users being upvoters of multiple Comments be named:
I would go with Upvoters.
Finally, I have a Comment relating to itself for the nested comments. Should this relation be named:
I would probably go with something like CommentResponses or CommentReplies.

Is it possible to access metadata about the prisma model?

Let's say I have a model in my schema.prisma file:
model Post {
id Int #id #default(autoincrement())
author User #relation(fields: [authorId], references: [id])
authorId Int
}
Having a variable called model in my server containing a model name
const model: string = [model name generated dynamically]
Using this string I want to know every information about this model. For example if this variable model happens to be Post, I want to know that it has fields id, author, authorId and also information about each field separately, like in the case of author which field in which model does it reference, in this example the model User the field id.
I'm aware that prisma generates a type for each model and that way maybe I can access the fields that way but that't not enough for me, I want information about each fields as well.
I search the prisma docs, also googled something like 'get meta information about model in prisma2' but I didn't find any solution. Is there a way to achieve this?
Yes, you can get all the metadata for your entire schema in the following manner:
const prisma = new PrismaClient()
// #ts-ignore
console.log(prisma._dmmf)
This will give you all the details for the models and relations. The reason this is not documented is that this is highly experimental and will change with releases, which is why it's used for internal purposes only.

LLBLGEN related array not populating in entity

i'm struggling with LLBLGEN and i guess ORM's in general.
i have created an entity, lets use a library example to explain:
i want to display a book object and also return a list of users who have loaned the book.
so i need to return the book object which contains a list of users.
DTO Book::
int bookId,
string bookName
additionally i wish to return with my book a collection of users who have loaned the book:
List<user> Loans
loans table might look like this:
int id
int userid
int bookid
currently my loans entity has now created this:
DTO Loans
int id
User user // user entity
Book book // book entity
im struggling to understand how this example would work in llblgen. can anyone assist with guidance or point me in the way of a tutorial?
at the moment, when i come up to update my model Book with a new loan associated to a book, im getting stackoverflow errors. i assume this is creating some sort of loop when attempting to update my Book object.
thanks
i noticed when running a profiler on SQL that the sql statement didnt include any join statements onto my relationship entities.
this was because my domain query didnt include prefetch items for my relationships, i added the following to my query:
var query = new DomainSearch<T>
{
SearchText = searchText,
PrefetchItems =
{
new Prefetch(typeof(Users))
}
};
To make sure, you are looking for a list of User entities that have loaned a particular Book entity. Is this the correct use case, or are you looking for a list of User entities that have borrowed the particular book?
Regardless, LLBLGen's support for these cases is great with referencing relationships between entities and using related entities quickly and easily.
Presuming you're looking up a book by unique BookId/ISBN/etc....
// Get the specific book entity
BookEntity book = new BookEntity(bookId);
foreach(UserEntity user in book.users)
{
// do stuff with list of users
}
It's just that simple assuming you've defined your relationships between entities.