typescript - Prisma: välj på många-till-många med flera villkor


Jag har två tabeller User och Post som är kopplade av en anpassad många-till-många-tabell såsom:

model User {
  id            Int      @id @default(autoincrement())
  name          String
  enabled       Bool
  posts         users_to_posts[]
}

model Post {
  id            Int      @id @default(autoincrement())
  name          String
  enabled       Bool
  users         users_to_posts[]
}

model user_to_post {
  user          user? @relation(fields: [user_id], references: [id])
  user_id       Int
  post          post? @relation(fields: [post_id], references: [id])
  post_id       Int
  @@id([user_id, post_id])
}

Jag försöker få en lista över användare baserat på en lista över inläggs-ID där användarna och inläggen måste vara aktiverade.

Hittills kan jag få de rätta användarna som är aktiverade om de har ett inlägg som finns i den angivna inläggsarrayen, men jag kan inte kontrollera om inlägget är aktiverat eller inte och jag kan inte heller filtrera inläggen (jag får alla inlägg som är kopplade till användaren om det finns en matchning)

Här är den (nästan) fungerande koden jag har:

import { PrismaClient, Prisma } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
    if (req.method !== 'POST') {
        res.status(400).send({ message: 'Only POST requests allowed for this route' })
    } else {
        const { posts_id } = req.query
        const posts_array = posts_id.split(",").map(function(item) {
            return parseInt(item)
        })
        const ret = await prisma.user.findMany({
            where: {
                enabled: true,
                post: { some: { post_id: { in: posts_array } }, },
            },
            include: {
                _count: { select: { post: true } }
                post: { select: { post: true }, },
            },
        })
        res.status(200).send(ret)
        // ...
    }
}

Jag kämpar fortfarande med att förstå hur jag kan multiplicera inbäddade urval utan att behöva förlita mig på TypeScript för att få frågan att fungera korrekt (vilket är långt ifrån idealiskt)

Svar #1

Såvitt jag förstår finns det två begränsningar som du behöver som inte är representerade i din fråga just nu.

  1. Returnera endast en user om posten i posts_array är aktiverad.
  2. Filtrera de returnerade inläggen från en user så att det endast innehåller enabled-inlägg.

Jag har uppdaterat din fråga för att lägga till dessa två villkor.

const users = await prisma.user.findMany({
    where: {
        enabled: true,
        posts: {
            some: {
                post_id: { in: posts_array },
                post: {  
                    enabled: true  // for constraint 1 (only check/match against the post_ids in post array which are enabled)
                }
            },
        },

    },

    include: {
        _count: { select: { posts: true } },
        posts: {
            select: { post: true },
            where: {
                post: {  
                    enabled: true   // for constraint 2 (only include the posts which are enabled)
                }
            }
        },
    },
})

Tänk på att users[SOME_IDX]._count.posts kommer att innehålla antalet av ALLA användarens inlägg (inklusive de som är disabled). Om du bara vill ha antalet aktiva inlägg måste du kolla längden på users[SOME_IDX].posts-arrayen.

Förresten, baserat på ditt schema är user_to_post-tabellen något överflödig. Du skulle kunna använda en implicit många-till-många för att modellera relationen mellan inlägg och användare.

Relaterade artiklar