Filter by id of a relation - prisma

I want to filter in prisma for a relation id and get the same entity, not the related one back. Simple example:
type User {
firstName: String!
lastName: String!
isOwner: [Meta!]! #relation(link: INLINE, name: "User_Meta_Owner")
id: ID! #id
}
type Meta {
owner: User! #relation(link: INLINE, name: "User_Meta_Owner")
area: Area! #relation(link: INLINE, name: "Meta_Area")
id: ID! #id
}
type Area {
id: ID! #id
name: String!
meta: Meta! #relation(link: INLINE, name: "Meta_Area")
}
In this case i want all Meta entities which have an owner with the id userID and an Area with the id areaID.
What is possible:
ctx.db.user({ id: 'userID' }).isOwner()
This gets all Meta without a filter for the area.
What i want is something like:
ctx.db.user({ id: 'userID' }).isOwner({ where: { area: 'areaID' })
ctx.db.metas({ where: [{ owner: 'userID' }, { area: 'areaID' }] })
Since the property area is only a relation, prisma doesnt give me the opportunity to filter or even get the ids.
ie:
await ctx.db.user({ id: 'userID' }).isOwner()
will result in an array of objects like:
[{
id: '...'
}]
My question is, is there any way to get my wanted result without deleting the relation and store simple strings?

I got an answer from prisma member to get this currently only working with model like this:
type Meta {
owner: User! #relation(link: INLINE, name: "User_Meta_Owner")
area: Area! #relation(link: INLINE, name: "Meta_Area")
ownerId: ID! #db(name: "User")
areaId: ID! #db(name:"Area")
id: ID! #id
}
So the id's needs to be exposed as scalars, so you can filter those.

Related

Amplify The instance member 'Products' can't be accessed in an initializer

I have a schema like this
type Store #model #key(name: "storesByDate", fields: ["type", "createdAt"], queryField: "storesByDate") #auth(rules: [{allow: private, operations: [read]}, {allow: groups, groups: ["Administrators"], operations: [read, create, update, delete]}]) {
id: ID!
name: String!
type: String!
description: String
createdAt: String!
Products: [Products] #connection(keyName: "byStore", fields: ["id"])
}
I added amplify to my project and it generated models like this with these errors
I don't think I am supposed to edit these files as they are auto generated. But can't understand why it generating wrong codes?
Please help

Prisma.io many to many relationships generates an error

I have a graphql schema
type Post {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
tags:[Tag!]!
}
type Tag {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
name: String!
posts:[Post!]!
}
So, a tag can be applied to many posts and a post can have many tags.
Prisma generates code without any issues, but running a graphql server gives
Error: Unknown type "TagOrderByInput". Did you mean "PostOrderByInput", "UserOrderByInput", "LikeOrderByInput", "TagWhereInput", or "CommentOrderByInput"?
at assertValidSDL (/home/andriy/app/apollo/prisma/node_modules/graphql/validation/validate.js:89:11)
I am using docker with Prisma and Mysql. Is it possible to have such a relationship? If so what I am doing wrong?
The solution was that in schema.graphql I have imported
# import Post, Query.postsConnection, Post.PostOrderByInput from "./generated-
schema.graphql"
And by deleting Post.PostOrderByInput the error disappeared.
# import Post, Query.postsConnection from "./generated-
schema.graphql"

How do you create a schema that can change depending on the user's input?

Just for funsies, I'm creating a similar app to UberEAT.
The database would probably hit the collection limit, so I created two separate collections.
First, I need the restaurant info, so I structured it like this:
var PlaceSchema = new Schema({
id: Number,
menuID: Number,
name: String,
cuisine_type: String, (eg; thai, korean, sushi ,etc)
address: String,
opening_time:Date,
closing_time:Date
});
Then I need to show the menu the restaurant have, the problem is each restaurant have a different number of dishes and prices, so the quantity is not constant.
This is how I structured my menu data, but I know it's completely wrong
var MenuSchema = new Schema({
id: Number,
parentID: Number,
name: String,
price: Number
});
any guidance would be great!
How about this to get started
for restuarant
var PlaceSchema = new Schema({
id: Number,
menusId: [Number],
name: String,
cuisine_type: String, (eg; thai, korean, sushi ,etc)
address: String,
opening_time:Date,
closing_time:Date
});
and for menus
var MenuSchema = new Schema({
id: Number,
placeId: Number,
dishes: [{name: String, price: Number}] //add any other dish related stuff here, like spiceness, app, entree, desert chef special etc etc
});
Now you can have multiple menus for a place, and multiple dishes in a menu.
You can even do array of places Id in the menu, which could be a case if bunch of restaurants same menu.
var MenuSchema = new Schema({
id: Number,
placesId: [Number],
dishes: [{name: String, price: Number}] //add any other dish related stuff here, like spiceness, chef special etc etc
});
Updated for drinks with default
here is an updated menu schema with drinks
var MenuSchema = new mongoose.Schema({
id: Number,
placeId: Number,
dishes: [{name: String, price: Number}], //add any other dish related stuff here, like spiceness, app, entree, desert chef special etc etc
drinks:[{
name: String,
price: Number
}]
});
Like I said in the comment, mongoose doesn't really have any default for arrays.
But we can write a pre save hook to take care of this.
MenuSchema.pre("save", function (next) {
if (!this.drinks.length) {
this.drinks.push({name: "No Drinks", price: 0}); //null or 0 whichever you pefer
}
next();
});
This will default in a default object as described above.
P.S. This defaulting drinks as "No Drinks" doesn't feel right though. Maybe keep it as an empty array, and when we need to use it in the code, to display or whatever just check for the length.
if (!menu.drinks.length) {
console.log("No drinks");
}

MongoDB schema design for multiple user types

I'm about to build a Node.js+Express+Mongoose app and I'd like to pick the community's brains and get some advice on best practices and going about creating an efficient schema design.
My application is going to include 2 different user types, i.e "teacher" and "student". Each will have a user profile, but will require different fields for each account type. There will also be relationships between "teacher" and "student" where a "student" will initially have 1 teacher (with the possibility of more in the future), and a "teacher" will have many students.
My initial thoughts about how to approach this is to create a general User model and a profile model for each user type (studentProfile model & teacherProfile model), then reference the appropriate profile model inside the User model, like so (A):
var UserSchema = new Schema({
name: String,
email: String,
password: String,
role: String, /* Student or Teacher */
profile: { type: ObjectID, refPath: 'role' }
});
var studentProfileSchema = new Schema({
age: Number,
grade: Number,
teachers: [{ type: ObjectID, ref: 'Teacher' }]
});
var teacherProfileSchema = new Schema({
school: String,
subject: String
});
Or do I just go ahead and directly embed all the fields for both profiles in the User model and just populate the fields required for the specific user type, like so (B):
var UserSchema = new Schema({
name: String,
email: String,
password: String,
role: String, /* Student or Teacher */
profile: {
age: Number,
grade: Number,
school: String,
subject: String
},
relationships: [{ type: ObjectID, ref: 'User' }]
});
The downside to option B is that I can't really make use of Mongoose's required property for the fields. But should I not be relying on Mongoose for validation in the first place and have my application logic do the validating?
On top of that, there will also be a separate collection/model for logging students' activities and tasks, referencing the student's ID for each logged task, i.e.:
var activitySchema = new Schema({
activity: String,
date: Date,
complete: Boolean,
student_id: ObjectID
});
Am I on the right track with the database design? Any feedback would be greatly appreciated as I value any input from this community and am always looking to learn and improve my skills. What better way than from like minded individuals and experts in the field :)
Also, you can see that I'm taking advantage of Mongoose's population feature. Is there any reason to advise against this?
Thanks again!
You could try using .discriminator({...}) function to build the User schema so the other schemas can directly "inherit" the attributes.
const options = {discriminatorKey: 'kind'};
const UserSchema = new Schema({
name: String,
email: String,
password: String,
/* role: String, Student or Teacher <-- NO NEED FOR THIS. */
profile: { type: ObjectID, refPath: 'role' }
}, options);
const Student = User.discriminator('Student', new Schema({
age: Number,
grade: Number,
teachers: [{ type: ObjectID, ref: 'Teacher' }]
}, options));
const Teacher = User.discriminator('Teacher', new Schema({
school: String,
subject: String
}, options));
const student = new Student({
name: "John Appleseed",
email: "john#gmail.com",
password: "123",
age: 18,
grade: 12,
teachers: [...]
});
console.log(student.kind) // Student
Check the docs.
One approach could be the following:
//Creating a user model for login purposes, where your role will define which portal to navigate to
const userSchema = new mongoose.Schema({
_id:mongoose.Schema.Types.ObjectId,
name: {type:String,required:true},
password: {type: String, required: true},
email: {type: String, required: true},
role:{type:String,required:true}
},{timestamps:true});
export default mongoose.model("User", userSchema);
//A student schema having imp info about student and also carrying an id of teacher from Teachers Model
const studentSchema = new mongoose.Schema({
_id:mongoose.Schema.Types.ObjectId,
age:{type:Number},
grade:{type:String},
teacher:{type:mongoose.Schema.Types.ObjectId,ref:'Teachers'}
},{timestamps:true});
export default mongoose.model("Students", studentSchema);
//A teacher model in which you can keep record of teacher
const teacherSchema = new mongoose.Schema({
_id:mongoose.Schema.Types.ObjectId,
subject:{type:String},
School:{type:String},
},{timestamps:true});
export default mongoose.model("Teachers", teacherSchema);

MongoDB Schema: Array with multiple fields?

I'm trying to create a schema for users to store their favorite shoes. Right now, I have the following schema:
local: {
email : String,
password : String,
}
How do I add an array of shoes such that when the user clicks on a button, the database will add the shoe brand and size to the User object? So something like:
favorite_shoes: { brand: xxxx size: xxxx, brand: xxxxx size: xxxxxx}
for each user. How would I do this/how would the schema look like?
Your schema will look like this:
{
usernam: String,
email: String,
password : String,
favorite_shoes: [ { brand: String, size: Int}, {brand: String, size: Int} ]
}
You don't have to create favorite_shoes field beforehand. It will get created first time you set its value.
If you want to avoid shoes repeating in the list use $addToSet:
db.users.update({usernam: "username"}, {$addToSet: {favorite_shoes: { brand: "Adidas", size: 12 } }});