Good morning/afternoon/evening! I'm trying to fig...
# orm-help
t
Good morning/afternoon/evening! I'm trying to figure out how to subquery data with Prisma. Eg. I would like to get Resources of certain Factory, but there is either Cell or Department -table between. I guess it's doable with query and without filtering, but what's the magic keyword?
Copy code
this.prisma.resource.findMany({
    include: {
      department: true,
      cell: true,
    },
  })
).filter(
  (resource) =>
    resource.department.factoryId == factoryId || resource.cell.factoryId == factoryId,
);
a
Copy code
this.prisma.resource.findMany({
    include: {
      department: {
          resource: true
      },
      cell: {
           resource true
      },
    },
  })
).filter(
  (resource) =>
    resource.department.factoryId == factoryId || resource.cell.factoryId == factoryId,
);
t
The question is more like how to do without post-filtering the results. Can it be done in the Prisma? Something like:
Copy code
this.prisma.resource.findMany({
    include: {
      department: {
          resource: true
      },
      cell: {
           resource true
      },
    },
    where: {
        OR: [
        {department.factoryId: factoryId },  // department.factoryId <<-- does not work
        {cell.factoryId: factoryId}
        ]
  })
)
Or if it shouldn't be done in Prisma, that's fine too. Just trying to figure out the best approach :)
a
you can filter by using filters as args in your findMany
Copy code
@InputType()
export class EnumRoleNullableFilter {

    @Field(() => Role, {nullable:true})
    equals?: keyof typeof Role;

    @Field(() => [Role], {nullable:true})
    in?: Array<keyof typeof Role>;

    @Field(() => [Role], {nullable:true})
    notIn?: Array<keyof typeof Role>;

    @Field(() => NestedEnumRoleNullableFilter, {nullable:true})
    not?: NestedEnumRoleNullableFilter;
}
then in my resolver with prisma
Copy code
@Query(() => UserConnection)
  async listUsers(
    @Args() { after, before, first, last }: PaginationArgs,
    @Args({ name: "query", type: () => String, nullable: true }) query: string,
    @Args({
      name: "roles",
      type: () => EnumRoleNullableFilter,
      nullable: true
    })
    roles: EnumRoleNullableFilter,
    @Args({
      name: "orderBy",
      type: () => UserOrderByWithRelationAndSearchRelevanceInput,
      nullable: true
    })
    orderBy: UserOrderByWithRelationAndSearchRelevanceInput
  ) {
    const edgingUserNodes = await findManyCursorConnection(
      args =>
        this.prismaService.user.findMany({
          include: { entries: true },
          where: {
            role: roles,
            email: { contains: query || "" }
          },
          orderBy: orderBy ? { ...orderBy } : undefined,
          ...args
        }),
      () =>
        this.prismaService.user.count({
          where: {
            role: roles,
            email: { contains: query || "" }
          }
        }),
      { first, last, before, after }
    );
    return edgingUserNodes;
  }
when I include USERS and SUPERADMIN in my roles to return, there are 7 users returned when I omit USERS and only include SUPERADMIN, only I'm returned notIn is somewhat redundant here -- just included it to show that I could have used notIn: ALL_ROLES_EXCEPT_DESIRED so I'd throw ADMIN MAINTAINER and USER in there to only have SUPERADMIN roles returned there is also the orderBy _relevance approach you can see in the allEntries query below -- check out the docs on filters and orderBy
ahh nevermind, I understand more clearly now
you're looking for XOR
Prisma.XOR
-- though I modified some of the types they have under the hood in my codebase this would work
Copy code
export type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };

/**
 * @type XOR is needed to have a real mutually exclusive union type
 * @url
 * <https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types>}
 */
export type XOR<T, U> = T | U extends Record<string, unknown>
  ? (Without<T, U> & U) | (Without<U, T> & T)
  : T | U;
and then use
XOR<arg1, arg2> mutually exclusive union
or you could use
Copy code
/* Makes an interface with all optional values to accept ONLY one of them */
export type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<
  T,
  Exclude<keyof T, Keys>
> &
  {
    [K in Keys]-?: Required<Pick<T, K>> &
      Partial<Record<Exclude<Keys, K>, undefined>>;
  }[Keys];
t
XOR or OR is one part of the question. The main point here was to understand, if fields of nested tables can be used in the where-section