Jonathan Marbutt
09/20/2022, 7:32 PMcontacts
and a table addresses
. Table addresses
has a contactId
and isPrimary
. And contacts
has a primaryAddressId
in the table.
If someone updates or adds an Address that isPrimary = true
then it should set the contact’s primaryAddressId
.
So where would you as a prisma dev have this live?
• Database Trigger
• Middleware
• Just my api code?
• Somewhere else?
This is actually a part of a bigger internal discuss I have been having and was curious this community’s thoughtsJonathan Marbutt
09/20/2022, 7:58 PMJonathan Marbutt
09/20/2022, 7:58 PMMuhannad
09/20/2022, 8:14 PMIf someone updates or adds an Address that isPrimary = true
Muhannad
09/20/2022, 8:23 PMAnd if you are building a lot of business logic like this as middle ware, how to you manage it from getting out of hand?
We probably have 50-100 rules like thisfrom my experience, you could have a queue (SQS, Kafka …etc) you can push messages to the queue whenever you have logic to be done in the consumer
Jeremy Hinegardner
09/20/2022, 9:17 PMprimaryAddressId
from the contacts table, and then add a partial unique constraint on addresses(contactId) where isPrimary = true
- this would make it so that for each contactId in the addressed table, they can have only 1 row where isPrimary is true, but lots where isPrimary is false.Jonathan Marbutt
09/20/2022, 9:20 PMJeremy Hinegardner
09/20/2022, 9:27 PMprimaryShippingAddressId
to the customer etc.Jonathan Marbutt
09/20/2022, 9:29 PMJonathan Marbutt
09/20/2022, 9:30 PMJonathan Marbutt
09/20/2022, 9:31 PMJonathan Marbutt
09/21/2022, 1:53 AMJonathan Marbutt
09/21/2022, 1:56 AM@relation
attribute to have a 1:1 relationship with the primary address if the isPrimary
was set trueNurul
09/21/2022, 12:10 PMLooks like upstash is interestingApart from upstash, you can also have a look at zeplo.io
Jeremy Hinegardner
09/21/2022, 4:17 PM@relation
attribute to load in the primaryAddress
as a relation via the prisma schema since all the @relation
items need to be fields on the model / in the database. And this may boil down to doing all those business rules in another layer of the application. You could do it with a middleware I think, and do a test on params.odel == 'Contact' && params.select == 'select'
or something like that, although I probably wouldn't do that as that may not be an appropriate use case, since that would run on every db query (https://www.prisma.io/docs/concepts/components/prisma-client/middleware#performance-and-appropriate-use-cases)
Since this is a business rule, that is getting some enforcement support from the db, along with the other 50-100 business rules associated with your models, this is where you would probably need a separate layer on your application that handles the business rules, and then those delegate to prisma for persistance. So you're probably not using the prisma models directly, but those are the core data structures for some other class. Or use custom models on top of the existing ones -- https://www.prisma.io/docs/concepts/components/prisma-client/custom-models#wrap-a-prisma-model-in-a-class - For this particular primaryAddress
case - this is probably what I would do - inherit from the prisma class and extend it with a primaryAddress
method -- this is just an example, not tested at all
import { PrismaClient, Contact } from '@prisma/client'
class Contact {
constructor(private readonly prismaContact: PrismaClient['contact']) {}
function primaryAddress() {
return this.prismaContact.contacts.find(contact => contact.isPrimary);
}
}
Jeremy Hinegardner
09/21/2022, 4:28 PMJonathan Marbutt
09/21/2022, 4:31 PMJonathan Marbutt
09/21/2022, 4:33 PMJonathan Marbutt
09/21/2022, 4:34 PMJeremy Hinegardner
09/21/2022, 4:48 PM