Laravel Advanced - Polymorphic Relationship

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys welcome to lara tips in today's video we'll be talking about one too many polymorphic relationship one to one polymorphic relationship and one too many polymorphic relationship are kind of similar so i'll be only discussing about one-to-many relationship here also one-to-one relationship is kind of rare in the real life scenario so that's why i'm not covering that but i'll also i'll show you how to define a one two one polymorphic relation only but in whole video we'll be talking about one too many polymorphic relationship also there is one important thing that we need to know about the polymorphic relationship which i'll be telling you at the end of the video so make sure to watch this video till the end okay now first of all let's see in which situation do we need this polymorphic relationship for that i have created excel sheet here so suppose let's say we have this product stable and a comments table and all of these comments are related to the product since we have a product id as a foreign key here and we also have a posts table so we only have these three tables so let us ignore these post comments and podcasts table for now so let's say we only have these three tables yeah then we have comments related to the products but we don't have any okay comments for the posts yeah so let's say a client comes and says we also need a commenting feature for the posts as well now we need to implement that for that we can implement this in two ways let's see both the cases here okay the first case is we can create a next table the post underscore comments table and we can simply copy all these fields here and simply paste it here and just replace this post under sorry this product underscore id with the post underscore id here yeah so we will be creating a new table here and now we can get all the posts uh comments of the post by using has many relationship here so there's not a problem here so this is one way of implementing it now there is another way of implementing it so let me show you that we can simply add a type column here in this comments table yeah and so whenever we add a comment to a products table then we'll add that type as the product and whenever we add comments to the post then we'll simply add that type to the post so let me show you what i'm telling here so let me just shift it down and in case of the product id we'll write here those who can comments here so in this case either product or the post we can have comments for them only so if we go in the label documentation here so in here we can see here the convention is like this so we'll be adding able in the in here yeah so let's follow this here so now in case of the product id we'll be writing commentable id and comment table type yeah so as i told you before whenever we add a comment for the products we'll be adding here in the commentable id we'll be adding id of the product and in the type we'll be writing products and whenever we are adding a comment for a post then we'll be writing here the in the comment table id there will be a post id and in the comment table type there will be the posts yeah as the value so this is another way of approaching it so if we do it like this then the same table will work for both products and posts yeah and if we go in this approach the first one then we need to create extra table yeah suppose let's say in the future again the client comes yeah and we also have this podcast table and we also want a commenting feature for that then if we go if we had gone this way then we had to create again another table and we let's say that that can be post comments then it will add a complexity so that's again in the future we want commenting system for another feature then we have to again create another table for that so that would be very difficult for us to maintain and if we go in this way in this way then we don't have to create any other extra table just we can use the same table here and it will work for all so this is called polymorphism so if you guys don't know what is what a polymorphism is that a same thing can occur in different form that is called polymorphism so here the comment is the same thing for product posts and podcast here so a comment can occur as a comments for the product it can also occur as a comments for posts and it can also occur as a comment for the post podcasts so it can occur as a comments for in a different form so this is called polymorphism that's why the relationship is also known as polymorphic relationship okay now let's see how to implement this in our laravel application so for that i have already created the models and migrations for that so now if i go here in my vs code now here are the magazine the posts table migration here we can see here the title slog and is active fields here and in the posts table we have also all these fields all these fields are from my previous youtube video tutorial so i have kept them as is so you can see here all the fields here and in the comments table we can see here it is a slight different here so we have this user id i have just kept it because only a user can comment so i have just left it here and here is a body and is active field and we have mobs here yeah table mobs commentable it will automatically create two columns in our table so which will be that i have shown here commentable id and comment table type it will just suffix here id and type here and it will create two tables for this and it will also do one more thing which is it will create a index for them so it will create a composite index yeah or compound index whatever you want to call it so it will create a index like this table index comment table type first it will register comment table type and then it will register commentable id so it will create an index like this as well so we don't have to type three different lines yes so simply the single the single line will add commentable type column commentable id column and it will add commentable type and id composite index here so let me just remove this now we have these yeah and we also have the products table so all the other these methods you are seeing here these are from a previous tutorial so let us just ignore this so this is also showing the comments has many relationship because i have covered this in my one to many relationship video so let us just ignore this for now and i'll be showing you how to define a relationship after that so we have a products table we have a posts model sorry and we have comments model as well okay we have seen all these things now let's see how to define a polymorphic relationship here so if i go here in the documentation here now you can see here now if you see here in the posts model here yeah we have a video here what i have taken as product yeah so now we have a post model so post can have many comments and a product can also have many comments so we can define a relationship as morph many now let me go in the model and define that so far a product can have many comments yeah so in the hash menu we had has many now this has turned into the polymorphic relation now we will convert this into morph many okay after that we have to also pass a second parameter here now the second parameter name will be let me show you here in the comments migration so it will be the same name that we have passed here so if we are adding here comment table then it should also be commentable here okay we have defined a comments relationship so the same relationship will be in the post model as well because a post can also have many comments so we will simply define like this now if we had a one-to-many polymorphic relationship then instead of more many we just say morph one yeah here also we just say morph one and when saving the comments or maybe something that has only one to one relationship then we have to make sure that only one data is saved in the table now here we are discussing about many too many one-to-many polymorphic relationships so i'll just add more many here yeah okay now a product can have many poor or many comments and a post can also have many comments but a comment can be related to either post or product both yeah now let us go to the comments model here now and let's define a relationship here so it can either relate to post or product yeah it can relate to both now for that we have to define a method here let's say if a comment was only related to the product then we could simply create this product method here and define a belongs to relationship but here it can relate to both now there's a different way of handling it we can say public function and give the same name that we have given in that morphs yeah so which would be this comment table now we have to return here this morph two here okay now as i said you this name should this commentable name should be same that we have defined here in this mob's method here here okay let's say you don't want the commentable name you simply want different name yes let's say mo dl yeah i'm very bad at naming things maybe you are good so you can give any name that you want here okay let's see more here then we have to give that comment table as a parameter here to the mob 2 so if we give it like this then we can give any name here that we want yeah now we want to follow the convention laravel convention so let us define the commentable name there so now if we call yeah we can access the relationship this commentable relationship from the comments model as comment and arrow and comment table which we can access as a property and if we say comment table then if this comment is related to product then it will give us the product model and if it is related to the post then it will give us the post model so we'll see that in action as well okay now let's see how to add a comment to a product or post and as well as editing and updating those things in the tinker well so now if i go here in the tinker well so let me show you in the database as well so in here database we have these tables so currently i have already seated one one data here so i have one product here and one post here and i don't have any comments okay now if i go here in the tinker well let us find the first product so we have found a first product now let us try to save a comment to a product so we can do it like this item this comments is the relationship that we have defined in the products model here so we can just access these comments so this works similarly that of the has many relationship exactly the same so let's say now we want to create then there is a create method here yeah now we want to create comment so let's go and see in the database which fields do we have so we have here user id user underscore id i also have the user with the id of one in my table in the users table so let us just use that for now and this comment table i type and commentable id will be automatically inserted by laravel for us because it knows that we are adding this comment for this product yeah so it in the commentable type let's see what it will add i'll show you here and in the comment table id it will add the id of the product here and we have a body field here as well so let us define that and we also have this is active colon now for that let us write one yeah so it will be the active one and this created and updated will be automatically added by laravel the current timestamp will be added there now if i run this code here now you can see here it is returning me the comment that is been added to the database now if i go here in the database and refresh now you can see here all the fields are added here so the body field and its active field is the same and you user id is the same that we have added and these two are automatically added by laravel and these as well now in the comment table id we have the id of the product yeah the id of the product one and in the comment table type we have app models product it is simply adding the path of the product model so if i go in the base code and if i show you here in the product so it is inside the app models folder and the name is product yeah so it is simply adding app slash model models slash product here so you can see here so it is simply adding okay let's see if we add a comment for let's say we want to add post so everything would be same because we also have the same relationship in the posts uh model so it will work the same way let's say the post comment here yeah and let us just add here as a zero and if we do it like this and run this code here and if we go here in the database and refresh now you can see here it is adding the post model path and if we go here in the posts model you can see here it is app models and post and here also you can see here app models post and you can see here it is zero and the post model comment is here so we can store the comments on the post or product in the same way we can also add multiple comments to a post yeah similarly to that of the has many relationship now we can just say create many here and we can add them as array here like this so let me also add another here yeah so we can say here so let us add one as active and another as inactive and the post comment multiple one and multiple two now if we if i run this code now you can see here it has added two comments and it is returning the both comments here now if i go here in the database and refresh here now you can see here it has added both comments here one is active and other is inactive so we can similarly add the multiple comments to a product in the same way here so we'll simply find the product here and we can simply add in the same way now we have seen how to add a comment or multiple comment to our product now let's see how to update them so to update a comment so we can do it in two ways we can either update it using a relationship or we can simply update it by using the same model okay now let's say we want to update this with the id of three comment yeah now if i say let's say we want to update it using a relationship now we can do it where id is one so since we are accessing comments from here here we will be getting the comments comment query builder so we can when we say id here like this then we will be getting the comment with the id of this one yeah now if we want to update like this then we can simply pass update method here and we can say let's say we want to update the body and let's say updated here now if i run this code it is saying 0 here because we have passed the id here yeah and this id is related to the um product and it is not related to the post here we are see because we are trying to update the post and it is not updating anything here so we can see here when i refresh nothing has changed now we are trying to update with the id of three here so let me add three here now if i run this code now you can see it it is returning one which means that it has updated one row now if i go here and you can see here for this here then if i refresh here now you can see here it has updated here so also you can simply say comment find id of 3 and update it yeah updated directly now if i say run and if i come here and refresh now you can see here it has updated so you can either use by the relationship or you can directly update using like the syntax okay now let me show how to update multiple rows using relationship yeah so let me just undo the changes here and let's say we here are okay the posts has a single post has three comments here yeah and one is active and other two are inactive here now let's say we want to update all these uh inactive to the active yeah we want to make them active now what we can do is here simply item comments and update like this if we do it like this it will apply to all the comments of this item so which is post for now now if i say here like this now here is underscore active and if i do one here so just before executing this let me show here so here you can see here different timestamps here for all these three now if i go here and and also here it is one and one is active and two are inactive now if i run this code now it is showing me three here yeah so it has updated all these three not only those that are inactive but all those three now if i refresh here you can see here all the time stamp are same because they are all updated at the same time now we don't want to update or we don't want to make active those are already active yeah so for that what we can do is so let me make them inactive again from here so these two are inactive and this is active yeah so we only want to make active those that are not active so we can simply say where and we can say is underscore active as one sorry zero so those who are not active convert them to active now if i run this code you can simply see here it is returning me two too if i refresh here so you can see here these two are updated and the time is time for this and this is same and this is different it means that it has only updated those two rows so we can update the multiple rows like this okay let's say now we're going to delete some comments from this relationship yeah then what we can do is comment where id is let's say we want to delete this one from here yeah and delete like this we can either delete it like this or we can directly delete it from the model as well so let's say we want to delete it like this with the id of 2. now if i run this code here it is returning me one because it has deleted one row now this should be gone here with the id of two now you can see here that is deleted we now let's say we want to delete all the comments from this post then simply remove the square yeah and it will get all the comments and it will delete all of them here like this okay now let me execute this code first so you can see here it has deleted two rows now if i refresh here if the two rows are gone okay now let's say you only simply want to delete comment using the modal comment then you can say find yeah and you can say did it here so let's say find the id of one here and let me execute this and if i go here that is also deleted so as you can see we can delete and update um in multiple ways so we have seen how to update the database create and as well as delete now let's see how to access the comments that have that are stored here so before that let me seed some data okay i have seeded some data here so we have two products and we have two posts here and for each post or product we have five comments so for the product with the id of one we have five commands for product with the id of two we have other five comments yeah and for the posts with the id of one we have five comments and post with idf2 we have five comments here some of them are active here and some of them are inactive now to access the comments from a product we can do it like this so this is also same as that of the has many relationship here let's say we want product here fine with the id of one like this now to access the all the comments we can simply say for product you can simply access is like a property yeah now if i execute this now you can see here i am getting all these five one two three four and five comments here all the comments are of this product here so you can see here so the comment table type is product and commentable id is one for all these yeah so i am simply getting all the comments now if i convert this into post and if i run this code yeah you can see here i am also getting all the comments for the post we can simply access comments from the post and product in the same way here yeah now let's see the inverse of this relationship how to access either product or post from a comment okay let's say we have a comment yeah here let's say only see here yeah so comment find with the id of one so if i show you that in the database here it is comment with the id of one this here yeah so it is of the product now as you if you remember that in the comments model we have defined a relationship like this comment table then we can access this simply as a property now if i go here in the tinker well and let's say if i say comment table like this we will be getting product because this comment is related to a product now if i run this here now you can see here we are getting a product model here yeah and all the data that is related to our product now if you go in the database and let's see a comment of a post here okay see this is the post comment yeah so id is 13. now if i go here and add id 13 and if i access a comment table here i will be getting this post with the id of one now if i run this code now you can see here i am getting paused so with the same property we are get getting either product or post depending upon which comment it is so in this way we can access the product or post from the comment okay now let's see this in the action in the browser yeah so here so let me go to the home controller here as you can see here i have passed here the product with the idf one so let us assume that we are visiting the detail page of our product and we will be seeing their product title and all the information of the product as well as all the comments of that product yeah now let us assume that and here we are finding the product with the id sim we could get this product either from the url yeah we can from the url we can get the id or slog and from that we can find the product and we can simply pass it from here okay we have passed the product and in the data is present in the welcome view here welcome.blade.php and i have simply shown the title of the product and all the comments that are related to the product yeah now let me go to the browser from here by clicking on this link here now if i visit the home page now i am seeing the title of that product with the id of one yeah if i show you here in the database here in the product the id is this starts with the a and here is the same same title and all the comments of that product so there are five comments so i am showing all the five comments of this product okay in this way we can show the comments of a product yeah so here if we see here in the view here so i am simply accessing the comments from the product yeah okay now let's say we only want to show the active comments yeah now if i so here in the database here comments so for the product with the id of one so you can see here there are only three active comments and two are inactive now we only want to show the active one so we can do that in two ways so we can do it in the view or in the controller so let's do that in the view first we can simply convert this property into a method and we'll get a relationship here which is also a query builder on the comments model so we can say where active is it equal to one and simply get the results here now if i go here in the browser i should see only three comments here so now you can see here i can only get three comments so we can also do it in the controller so adding logic to a blade view is not a good idea yeah so it will just clutter our view simply pass the variables and just show them in the view don't use any logic in the view okay now let me remove this one here yeah if i go in the home controller what we can do is we can simply pass the relationship by using eager loading here yeah so if i do it like this with comments like this yeah so all it will get all the comments from the product then if i go here and refresh the page here we'll be getting all the products that as we have got earlier now to get all the active comments we can simply pass it as an array here and we'll find return of closure here and here we'll get the query builder that we have got and it will be related to the comments and we can simply say here query where is active to one now if i go here and refresh the page now you can see here we are only getting the active comments yeah let's say you want to show the inactive simply convert it into zero and refresh the page now we are getting only two comments which are inactive yeah so however you would never want to show the inactive comments so we'll only be showing active comments which are three here now let's say we want to do the same thing for the post it's very easy so simply find the post yeah first with the id of one now let me go in the here and let me just write post in place of the product this will work the same way yeah because they both are related to the comments using polymorphic relationship and they are same here we don't need to change anything here so here is the name is the product in the real life i would change this product to post but in this screencast i am leaving it here like this now if i go here in the browser and refresh the page now you can see here i am getting the post with the id of one so the name let me show you here in the database as well so you can hear the name the title here and the title here is same and all the active comments of this blog are shown here because we have only shown the active ones so in this way we can get all the comments of the product or a post using polymorphic relationship like this so we have seen this yeah okay now let's say in our admin dashboard panel we are showing the list of all the comments so it can be either related to post or product we don't care we are showing all the list of the comments and we want the admin to filter those comments using some uh filters yeah so let's see how to do that but i'll be only showing you here in the front so for that i have also already created a route yeah so you can see here the route i have created comments route and comment controller we are going inside the index method yeah let me go here inside the index here and you can see here i have simply got just taken all the comments and simply passed it to the comment blade dot view and you can see here this comment.blade.view is here inside the view folder now what i have done is i have simply looped through all the comments and i have shown this using comment table so this commentable will get either post or product then we are getting the table name so if so this will give us the model and there is a get table method in the model by which we can get the table name of that model yeah so if we get product then we will get the table name as products here like this and here if the comment table is post we'll be getting posts here yeah the table name now we are getting the title from the comment table so title of the post or title of the product and also we are getting the comment body and comment created at when it was created so d for humans would give us like two minutes ago or like let's say 10 minutes ago yeah it will just give us that kind of time stamp here now if i go here in the browser and just click on the comments here now you can see here i am getting all the comments here and you also saw it took a little bit while yeah so all that was because we are running into n plus one query problem now if i go here and show you here in the queries list oh my god we are running 21 queries here and among which if you see her 21 statements were executed and 20 of them are duplicate here so we can see here all those duplicates yeah data here now let's see how to solve this as well so why we are getting this i'll show you that as well since we are getting here in the comments control we are getting only comments here here and we are accessing the comment table from here so whenever we access this comment table then we'll be running one more extra query to get that comment table yeah it is very easy to use using the model but the performance will decrease of our application so we are running extra queries here now to minimize this what we can do is either eager or lazy loading now here we can say here with we can do eager loading like this and just give the relationship name and which is common table now if i go here so you can see here we are getting a 21 queries now if i just refresh here now you can see here it is much faster and we are only running three queries so we are drastically reducing the number of queries that is being run here so this will really increase the performance of our application so we have seen here so so this is the this we are getting from the that get table name yeah from that method so these are the comments from the products and these are the comments from the posts okay now let's say we only want to show the comments of the products yeah now what we can do here so let me show you that in the documentation as well now if i go here in the documentation you can see here querying relationship here you can see here querying polymorphic relationship and here we can see here all this kind of relationship yeah so now we only want to show the comments of the posts yeah so we can do it simply like this so in the has many relationship we had a method called where has but in a polymorphic relationship we have a method name as where has morph yeah so let us simply copy all this here and if i go in the comment controller here and we can see here where has morph and simply paste here all the code okay now let me just remove this one for now here and instead of this now we can if we we have to pass the full path of the class here okay so let's say we only want to get the comments of a post so we have to say post class here like this so if we pass only post here we'll only be getting the comments of a post yeah and this word has more will first get the first parameter would be the name of the relationship which is this comment table here they are same here now if i go in the browser and here if i refresh here now i should only see the posts comments all the comments related to post only here now if i want to see both then i have to pass here product as well like this now if i pass it like this then i'll be getting the comments of both products and posts here yeah and if we only want the products then simply remove this and just add this and we'll be getting this so it works like this here yeah okay now let me show both of them here yeah and if i go here in the documentation now you can see here there is a third parameter here function yeah so let me show you that as well so i have just simply pasted here so by using this third parameter we can filter these comments by the either post or product here okay let's say now we want to show all the comments of product only and that product should start with the title uh there are two products in our database and okay let's say this we want to show that it starts with this yeah this name so we are basically here showing all the comments of only the products whose title starts with this name yeah now if i go here in the browser and if i refresh here now i should only see five comments here so which is only related to that product only yeah so you can see here the product name all of them are they are starting from this okay now if i want to show all the comments of the product that name starts with this tolerance yeah so i can simply say like this yeah and it will show me all the comments of that product only now if we only want to show the comments of the posts we can simply say post here and if i go here in the database the post yeah let's say ex here yeah and simply pass e x here and it will only show the comments of that post only now if i go here and replace the page now i am only getting the comments from that post here now we have a post and a product whose name starts with the same word okay let me do that here for you so for the products we have this as per nature yeah and in the post let me just edit it from here and just add that here like this okay okay now here what we are doing is we want to get all the comments from post as well as product yeah and which title starts from this world now if i go here in the browser and refresh now you can see here i am getting all the comments from the product as well as post whose title starts with this word here so post also starts with word and we are not getting any other comments here so we can filter it like this okay now let's say we only want the active comments then we can simply say here pass that builder in this comments query here yeah so inside here we are getting the query for either post or product yeah and now here outside will be getting the query builder for comments so we can simply say where is underscore active as one and we'll only be getting the active comments so here we are here we are getting all the 10 comments and now we are only getting the active comments so we are getting only three comments from the product and three comments from the post which are only active here okay now let's say you want to show the comments from the product and post both but from the product you want to show all that all the comments that starts with this product title as this and let's say and for the posts you want the separate post comments yeah so let's see how to do that now here we have a second parameter we'll get here dollar type and here we will get the name of this so whatever we have passed here either post or product will be getting here yeah now let's say if type is equals to let's say post class then we simply want to just return this we'll just get all all the comments from the post whose name has started from this yeah now and if that is not the post then it will be product yeah so then here we'll simply return query where title like let's say if we go here in the products table so there in the idf2 we have this here so let me just copy this and just pass it here so we are getting all the comments of the post whose title starts with this name and all the comments of the product which title start from this name now if i go here in the browser and refresh the page here so you can see here all the products title is start with dolorean and all the posts title start with this yeah so you can see that here in the documentation as well so you can see here like this now let's say we want to get the comments from all everything yeah so as we have seen in the excel in the starting of this video we had a podcast as well so if we add any others table in the future then we don't want to go here and add again podcast here and all the other fields for that laravel has a nice syntax simply pass asterix here yeah if we pass astrix here it will get all the tables so it can be post it can be product it can be podcast yeah now if i go ahead in the browser and simply run here now it will give us the same results yeah it will work in the same way but the case is it will just use all that related models here now as i said in the beginning of a video there is one important thing to notice here yeah so if you see here in the database in the comments table so here we are storing the name the structure of our application and the database should not depend upon the structure of our application yeah we have to just isolate it so let's say in the future we wanted to store this products model somewhere other than in the models table yeah we can follow the domain driven design yeah we can if we follow that design then we might put these models in the specific folder related to that domain only yeah so in that case this path of the model would change again then our application would break in that situation so in that case laravel also has a handy feature for that now if i go here in the documentation here now you can see here in the custom polymorphic types here if i click here now if you see here we can give the name so what we want so for the products instead of this full path name what we want to add here we can define it like this for that simply go copy this here and go to the app service provider provider which is inside here also app providers and app service provider and inside the booth method simply just paste it here yeah and you can see here this release is illuminate database eloquent relations relation yeah so let me just import that here like this you can see here it is imported on the top here and it is here yeah now for the posts let's say post class we want it to be posts yeah and for the product we simply want it to be products since we have already done previously um here we have seeded the data so for that let me just update it and simply add posts here now if i go here in the browser and simply refresh the page now it would work the same way yeah as you can see i have done or changes this fields manually here because i have previously seeded those data and those data all added the path name but whenever you add this thing here in the app service provider and then whenever you add some comment or from the using the relationship then the laravel will automatically add this post's name instead of this post here so let me quickly show you that here first okay in the tinker well let me find the post here post find with the id of one here and post comments create yeah so now we can pass here user underscore id as let me just pass it as one here and body as the new comment and here is is active as one here okay now when we before did like this then it when it created a comment for a post it simply added the path of that post now let's see what happens now when i run this code here now you can see here it's given me the model and if i come here and refresh so we are in currently 20 id now if you see here in the 21 we are getting the posts here so all those things that i did manually you should not do that because whenever you create a post or so your comment for a post or the product it will automatically add this name this name here instead of the path yeah and we are very confident that our database is not coupled with our application structure so that's it guys that's all for this one-to-many polymorphic relationship so if you want to see more videos like this then please don't forget to hit that thumbs up button and also hit subscribe button thank you for watching have a great day bye
Info
Channel: Laratips
Views: 2,181
Rating: undefined out of 5
Keywords: laravel for beginner, laravel beginner tutorial, laravel tutorial for beginners, laravel 8 tutorial, laravel 8, laravel tutorial, laravel advanced, laravel 8 advanced, laravel advanced tutorial, laravel 8 advanced tutorial, polymorphic relationship, laravel polymorphic relationship, laravel 8 polymorphic relationship, laravel tutorial for beginners step by step, laratips
Id: zK6wsIAlMdI
Channel Id: undefined
Length: 44min 28sec (2668 seconds)
Published: Fri Oct 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.