Get data from secondary table in Prisma2 - graphql

I have a User table that contains user data. I also have a Relationship table that contains a parent_id and a child_id as well as the incrementing id. Each Parent can have many Children and I am trying to retrieve the array of children using the parent_id. I am currently getting an array, but the array only contains the Relationship table data.
How do I get the data from the User table? I was under the impression that because there is a relationship the following should work, but it doesnt.
query {
getChildren {
user{
id
name
email
}
}
}
The relevant code is as follows:
Query:
export const getChildren = queryField('getChildren', {
type: 'User',
list: true,
resolve: async (_parent, {}, ctx) => {
const userId = getUserId(ctx);
if (!userId) {
// TODO -think I might need to throw an error here
return;
}
const children = await ctx.prisma.relationship.findMany({
where: {
parent_id: userId,
},
});
return children;
},
});
schema.prisma:
model Relationship {
child_id Int
id Int #default(autoincrement()) #id
parent_id Int
child User #relation("Relationship_child_idToUser", fields: [child_id], references: [id])
parent User #relation("Relationship_parent_idToUser", fields: [parent_id], references: [id])
}
model User {
created_at DateTime #default(now())
email String? #unique
id Int #default(autoincrement()) #id
ischild Boolean #default(false)
name String?
password String
children Relationship[] #relation("Relationship_child_idToUser")
parents Relationship[] #relation("Relationship_parent_idToUser")
}

The query below should do it
prisma.relationship.findMany({
where: {
parent_id: user_id,
},
include: {
child: true,
},
})
You need to specify the include param explicitly to include the relationship in the output.

Related

Search By Column in Laravel/Lighthouse GraphQL API

currently i'm creating a GraphQL implementation of an existing API.
i want to create Search Function not with primary column, which is not id, but id_position.
here is my scheme :
type Query #guard {
subordinate(
positionId: ID
): [Employee!]! #all
}
type Position #key(fields: "id") {
id: ID
name: String
}
"Account of a person who utilizes this application."
type Employee #key(fields: "id") {
id: ID
name: String
id_position: Int
}
but, when I run this :
query EmployeeSubordinate($id: ID) {
subordinate(positionId: $id) {
name
}
}
{
"id" : 93
}
I ve got result all rows of employee, not employee with id_position = 93
how to solve this?
I think the problem is here
type Query #guard {
subordinate(
positionId: ID
): [Employee!]! #all
}
The #all is getting all records from DB #all docs
The correct way is this
type Query #guard {
subordinate(
positionId: ID
): Employee
}
I removed ! from Employee because your ID is not required, so in some cases it masy return null, i you handle like thatin backend.
And alsoe I removed [] because you no longer getting many Employee you just getting one.

Prisma many to many relations Query

I have a User model along UserRelationship model
I have created trainer/client relationship with the UserRelationship model.
model User {
id Int #id #default(autoincrement())
trainerRelationship UserRelationship[] #relation("trainer")
traineeRelationship UserRelationship[] #relation("trainee")
}
model UserRelationship {
id Int #id #default(autoincrement())
trainerId Int?
traineeId Int?
trainerUser User? #relation("trainer", fields: [trainerId], references: [id])
traineeUser User? #relation("trainee", fields: [traineeId], references: [id])
}
I am able to query the user also able to query their relationship
For eg:
const trainer = await client.user
.findUnique({ where: { id }, include: { trainerRelationship: true } })
The output i am getting here is like:
{
id: 1,
username: hellouser
trainerRelationship: [
{
id: 4,
trainerId: 1,
traineeId: 34
}
]
}
Now i want to fetch the details of the traineeId/trainerId user details, What should be my query?
Ok, so I have solved it by the below query, incase someone is stuck:
.findUnique({ where: { id } }).trainerRelationship({
include: {
trainerUser: true,
},
})

How to make self resolving array of object types with Prisma and GraphQL

Maybe the title is not accurate but I really don't know how to describe it anymore. I went through multiple documentations and descriptions but still couldn't figure it out.
I want to implement a basic social media like followers/following query on my type User. I am using MySQL and for that I made a separate table called Follow as it's a many-to-many connection.
Here is a pseudo-ish representation of my tables in the database without the unnecessary columns:
Table - User
user_id primary key Int
Table - Follow
follow_er foreign_key -> User(user_id) Int
follow_ed foreign_key -> User(user_id) Int
A user could "act" as a follow_er so I can get the followed people
And a user could be follow_ed, so I can get the followers.
My prisma schema look like this:
model User {
user_id Int #id #default(autoincrement())
following Follow[] #relation("follower")
followed Follow[] #relation("followed")
}
model Follow {
follow_er Int
follower User #relation("follower", fields: [follow_er], references: [user_id])
follow_ed Int
followed User #relation("followed", fields: [follow_ed], references: [user_id])
##id([follow_er, follow_ed])
##map("follow")
}
By implementing this I can get the followers and following object attached to the root query of the user:
const resolvers = {
Query: {
user: async (parent, arg, ctx) => {
const data = await ctx.user.findUnique({
where: {
user_id: arg.id
},
include: {
following: true,
followed:true
}
})
return data
}....
Here is my GraphQL schema I tried to make:
type Query{
user(id: Int!): User
}
type User{
id: ID
following: [User]
followed: [User]
}
So I can get something like:
query {
user(id: $id) {
id
following {
id
}
followed{
id
}
}
}
}
But I couldn't make it work as even if I get the the array of objects of {follow-connections}:
[
{
follow_er:1,
follow_ed:2
},
{
follow_er:1,
follow_ed:3
},
{
follow_er:3,
follow_ed:1
},
]
I can't iterate through the array. As far as I know, I have to pass either the follow_er or follow_ed, which is a user_id to get a User object.
What am I missing? Maybe I try to solve it from a wrong direction. If anybody could help me with this, or just tell me some keywords or concepts I have to look for it would be cool. Thanks!
I would suggest creating self-relations for this structure in the following format:
model User {
id Int #id #default(autoincrement())
name String?
followedBy User[] #relation("UserFollows", references: [id])
following User[] #relation("UserFollows", references: [id])
}
And then querying as follows:
await prisma.user.findUnique({
where: { id: 1 },
include: { followedBy: true, following: true },
})
So you will get a response like this:

Retrieving related model of a deleted model in Prisma 2

Hello guys here is the scenario i have;
model User {
id Int #default(autoincrement()) #id
...
posts Post[]
comments Comment[]
}
model Post {
id Int #default(autoincrement()) #id
comments Comment[]
...
}
model Comment {
id Int #default(autoincrement()) #id
post Post #relation(fields: [postId], references: [id])
postId Int
...
}
So i'm trying to delete a comment, and below is my approach
export const deleteComment = mutationField('deleteComment', {
type: 'Comment',
args: {
where: 'CommentWhereUniqueInput',
},
resolve: async (_, { where }, ctx) => {
let comment = await ctx.prisma.comment.delete({
where: where,
include:{
author: true,
post:true
},
})
return comment
},
})
But i'm having an error message which says 'Cannot return null for non-nullable field Comment.post.'
Any idea how i can solve it?
Thanks
Maybe with npm i #paljs/plugins
https://paljs.com/plugins/delete/
or https://www.prisma.io/docs/guides/database-workflows/cascading-deletes/postgresql

How to reshape a GraphQL (via Hasura) query response?

I have a CHAT_MESSAGE_FRAGMENT that returns all the message data from my Hasura graphql api.
However, the Gifted Chat react-native component requires the data in a specific structure so I'm attempting to convert it with the query below.
I'm able to alias all the top level data but can't figure out how to add a nested level of data.
I'm guessing it isn't possible but I thought I'd ask in case I'm missing something.
const GIFTED_CHAT_GROUP_MESSAGES_QUERY = gql`
query chatGroupMessages($chatGroupId: Int!) {
chat_message(
where: { to: { id: { _eq: $chatGroupId } } }
) {
_id: id,
# user: {
# _id: from.id, <== How do I add
# name: from.name, <== this secondary level?
# },
text: message,
image: image_url,
createdAt: created_at,
system: message_type,
}
}
${CHAT_MESSAGE_FRAGMENT}
`;
Assuming you already have chat_message.user_id -> users.id foreign key constraint set up, you'll also need to alias the from object in addition aliasing any of its nested fields:
const GIFTED_CHAT_GROUP_MESSAGES_QUERY = gql`
query chatGroupMessages($chatGroupId: Int!) {
chat_message(
where: { to: { id: { _eq: $chatGroupId } } }
) {
_id: id,
from: user: {
_id: id,
name
},
text: message,
image: image_url,
createdAt: created_at,
system: message_type,
}
}
${CHAT_MESSAGE_FRAGMENT}
`;
The secondary level of data is basically nested object queries in Hasura. You can nest any number of queries as long as a relationship has been created.
In this case, assuming the chat_message table has a user_id field, you can establish a foreign key constraint for chat_message.user_id -> users.id, where users is a table with id as primary key.
Once the foreign key constraint is created, Hasura Console automatically suggests relationships. Here user would be an object relationship in chat_message table.
Here's the official docs link for Creating a relationship

Resources