Prisma: choose from numerous options in a many-to-many relationship with various criteria

I have a unique scenario with two tables, User and Post, that are connected through a custom many-to-many table:

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])
}

I am currently trying to retrieve a list of users based on a list of post IDs, where both the user and the post must be enabled.

At the moment, I am able to fetch the correct users that are enabled if they have a post matching the provided post array. However, I am facing difficulties in checking if the post is enabled and filtering the associated posts (all posts are retrieved if there is a match).

Here is the code snippet that is almost working:

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)
        // ...
    }
}

I am still struggling to figure out how to perform multiple embedded selections without relying on TypeScript to correctly execute the query (which is not ideal).

Answer №1

It seems that there are two additional constraints required that are not currently reflected in your query.

  1. Retrieve a user only if the corresponding post in posts_array is enabled.
  2. Filter the returned posts of a user so that it only includes enabled posts.

I have made modifications to your query to incorporate these two conditions.

const users = await prisma.user.findMany({
    where: {
        enabled: true,
        posts: {
            some: {
                post_id: { in: posts_array },
                post: {  
                    enabled: true  // for constraint 1 (only consider enabled posts in posts_array)
                }
            },
        },

    },

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

Remember that users[SOME_IDX]._count.posts will give you the count of ALL posts by that user (including disabled ones). To get the count of enabled posts only, you need to check the length of the users[SOME_IDX].posts array.

On a side note, based on your schema, the user_to_post table may be redundant. Consider using an implicit many-to-many relation to model the connection between post and user.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process of changing a number to the double data type in JavaScript or TypeScript?

Within a single input field, users can enter various numbers such as 12, 12.1, 12.30, and 12.34. The challenge is to pass this value in a service call where only the value can be sent as a number but with two decimal points. let a = input //a will be a ty ...

Accessing different pages in Angular 2 based on user type

If I have four pages and two user types, how can we implement access control in Angular 2 so that one user can access all four pages while the other is restricted to only two pages? ...

You cannot access the property 'subscribe' on a void type in Angular 2

fetchNews(newsCategory : any){ this.storage.get("USER_INFO").then(result =>{ this.storage.get("sessionkey").then(tempSessionKey =>{ this.email = JSON.parse(result).email; this.newSessionKey = tempSessionKey; this.authKey =JSON.stringify("Basic ...

The latest issue encountered in @apollo/experimental-nextjs-app-support with Graphql Nextjs 13 has been identified

I am interested in utilizing mutation functions. apolloProvider.tsx "use client"; // ^ this file requires the "use client" pragma import { ApolloLink, HttpLink, SuspenseCache } from "@apollo/client"; import { ApolloNextApp ...

How would you define 'Idiomatic' in the context of Idiomatic Javascript?

During his initial discussion on TypeScript, Anders repeatedly mentions the term 'idiomatic javascript'. Can you clarify the specific definition of idiomatic in this context? I've attempted to research this on Wikipedia and Stack Overflow, ...

The specified type '{ rippleColor: any; }' cannot be assigned to type 'ColorValue | null | undefined'

I've been diving into learning reactnative (expo) with typescript, but I've hit a roadblock. TypeScript keeps showing me the error message Type '{ rippleColor: any; }' is not assignable to type 'ColorValue | null | undefined' ...

Having trouble utilizing Vue3 methods while utilizing the `<script setup lang="ts">` syntax

Looking to incorporate Vue into a non-Vue Class using the Composition API for a Chrome Extension project where having the entire thing as a Vue App doesn't make sense. The Vue Instance is being instantiated in the usual manner and then injected into ...

Unexpected behavior observed with Angular Toggle Button functionality

Having trouble implementing toggle functionality in Angular where different text is displayed when a button is toggled. I keep getting an error in my code, can anyone assist? See the code below: HTML <tr> <td>Otto</td> <td> ...

Creating interactive links in Next.JS with the help of styled-components

While working on a small side project, I encountered an issue with active links in my navbar using Next.JS. In React, you can easily use react-router-dom and its Link component with the activeclass attribute, but it seems like this feature is not availab ...

Countdown component in Ant Design failing to display correct date

I’m currently working on developing a specific date component using react in conjunction with antd. Below is the code snippet I am utilizing: import { Statistic, Col, Row } from 'antd'; const { Countdown } = Statistic; const deadline = Date.pa ...

Generate a basic collection of strings from an object

Looking at this object structure Names = [ { group: 'BII', categories: null }, { group: 'GVL', categories: [] } ]; I ...

Having trouble deploying my Express/Next app on Netlify

I am facing issues deploying my Next/Express app on Netlify. While the app functions perfectly locally, I encounter problems when attempting to deploy it using Netlify lambda function. Here are the links to my test git repositories: https://github.com/La ...

Dilemma: Navigating the Conflict Between Context API and Next.js Routing in React

Recently, I was following a Material UI tutorial on Udemy and decided to set up a Context API in Create React App without passing down props as shown in the tutorial. Later on, when I tried migrating to Next JS with the same Context API, I started encounte ...

The React type '{ hasInputs: boolean; bg: string; }' cannot be assigned to the type 'IntrinsicAttributes & boolean'

I recently started learning react and encountered an error while passing a boolean value as a prop to a component. The complete error message is: Type '{ hasInputs: boolean; bg: string; }' is not assignable to type 'IntrinsicAttributes & ...

The Crimson Thread when incorporating tsx into Next.js

https://i.sstatic.net/zXvPT.png While working with TSX in React and TypeScript, I encountered an issue. A red line appeared on the screen even though the project runs successfully. Can anyone explain why this red line is appearing and why the classes in T ...

Exploring the capabilities of dynamic pathname routing in Next.js

Consider this scenario: there is a path that reaches me as /example/123 and I must redirect it to /otherExample/123. My code utilizes next/router, extracting the URL from router.asPath. if(router.asPath == '/example/123') { Router.push(' ...

Having trouble implementing the Material UI time picker because it does not meet the required DateTime format

REVISE I recently switched my dataType from DateTime to TimeSpan in my code. I have a functioning MVC version that already uses TimeSpan, and the times are posted in HH:MM format. Now, I am unsure if the issue lies with the headers set up on Axios or if it ...

Learn the process of adjusting the Time Zone in Angular2-HighCharts!

I've been struggling for a few days now trying to adjust the UTC time in an area chart using Angular2-HighCharts. The backend API is returning timestamps which I then inject into the chart, but each time it's being converted to "human time" with ...

Is there a way to enable Tail Recursion Optimization in TypeScript?

const isPositive = (n: number) => n > 0; function fitsIn(dividend: number, divisor: number, count: number, accum: number): number { if (accum + divisor > dividend) { return count; } return ...

Arranging information within the Ngb-Accordion

Welcome to the code snippet showcasing how to create an accordion in Angular: <ngb-accordion [closeOthers]="false" activeIds="0"> <ng-container class="card" *ngFor="let post of Posts"> <ngb-panel title="{{post.title}} - ...