This episode is for members only

Sign up to access "Eloquent Relationships By Example" right now.

Get started
Already a member? Sign in to continue
Playing
32. Defining and using a has one of many relationship

Episodes

0%
Your progress
  • Total: 4h 18m
  • Played: 0m
  • Remaining: 4h 18m
Join or sign in to track your progress

Transcript

00:00
The first thing that we're going to do here is with the relationship types that we've already covered in the course, figure out how we're going to get the latest discussion or the latest post
00:09
for a discussion but not using a has one of many relationship. We'll see the issue with this and then we'll go ahead and implement this new relationship type. So the first thing that we haven't done is gone ahead and set up the actual discussion model relationships. So this is very very simple. It's something that we've already looked at and the type of relationship
00:30
you're going to be using most which is a has many. So we're going to say that a discussion has many posts and with that information what we can do is if we were creating out an individual discussion page we could just iterate through all of the posts. So what we want to do here is over on our template and let's just roughly do this, figure out how underneath here we can grab
00:54
the latest post. So let's just go ahead and dump our discussion and posts and we know that for each of them we get a list of the posts. Now what we could do here is we could go ahead and order these and then just grab the first one. So this comes back to the way that we use eloquent collections in Laravel. So we are going to say posts and I'm doing this within our blade template which
01:23
you should absolutely never do. There's no real need to do this. You would always do this at the controller or root level. So we're going to say posts and we're going to say latest. We know that that brings the latest post to the top and then technically we could just say first and then we could start to access any of this information. So each of these posts now even if we just have
01:42
one post is the latest post that we have. Now this is the whole reason for this has one of many relationship. Previously this is really the only way we would be able to do this. We would have to access the has many, we would have to find out the latest post or order this and then we would have to grab the first record and normally this would be done at the controller level or it would be done
02:06
in this case at the model level and I'll show you how that looks in a second. So this is not great but let's just output what the kind of information that we need here. So we want to say latest post by it's the latest post by and then we want to grab the latest post user. So in this case we would go into that post then we would access the user then we would access the name. So at the moment
02:27
our post model doesn't have a user so let's go ahead and fill that in really quickly here. We know that our post belongs to a user so this belongs to a user and let's pull that in and there we go so latest post by and then whichever user it is. So let's change this well we can't really can we because we've got the same user in here let's create another user in here
02:52
just so we can actually see the information change here and we'll go ahead and set for this post here to the second user and that will give us two different users. There we go so for the first discussion the latest post is by Alex. So this is working but it's not ideal the first reason it's not ideal is because we're doing this this kind of query building inside of our
03:18
blade templates which is not a good idea. So what we would have to do here is move this over to our model. So this is what we would previously do we would let's just take this out entirely just for now and put x there what we would have to do is inside of our discussion go ahead and create our a method in here maybe called latest post and then go ahead and return and return this so we're
03:48
referencing this and what we could do if we didn't want to perform an additional query in here this is entirely possible let's just look at this without this first of all so we would do that in here and then what that would mean is inside of here we could say discussion latest post invoke that it's not necessarily a relationship it is just grabbing the first model so this actually
04:11
returns to us a model or in this case it returns to us a post so we could even type into and then we would go ahead and grab the user and then we'd grab the name so that is a better solution it's still not great we can improve this by just accessing the relationship itself rather than making a entirely new query here and then we could go ahead and sort this so we could say
04:36
sort descending and that's by the created at date and then grab the first one give that a refresh and let's have a look here sort i think this is sort by descending yeah there we go so we get the same result here but we're not performing always an additional query now this is a mess anyway it's not the way that we want to do things which is the reason that this additional relationship type
05:01
was introduced in laravel has one of many so with that said let's take a look at how we do this i'm gonna go ahead and get rid of this latest post here i'm gonna get rid of this because we're starting completely from scratch and let's go ahead and introduce our new latest post relationship but actually doing this at the database level rather than having to pluck this out for every
05:22
single iteration so this relationship type is a little bit weird because what we're going to have to do here is say this has one and then go ahead and say that it has one post because remember we're getting the latest post it doesn't make sense to have multiple ones but with here we're going to say latest of many so it almost changed well we are chaining this on to has one has one
05:45
we've already looked at this is kind of like a modifier to grab the latest of many so now we've done this this is being done at the relationship level which means we can ego load it that's the whole point of this that we can add that speedings we can ego load and it's going to work in exactly the same way so let's go ahead and just dump this out so discussion and latest post and see what we
06:09
get here as you can see we get exactly the same thing we get the latest post this still contains the user because we get back a model which we can use we can ego load that as well but let's go ahead and just output this data just for now and there we go exactly the same thing but this time this is being done at a relationship level which the key thing here is that we can now ego load
06:31
this so let's go ahead and just pull in laravel debug bar just to see what we've got here and sure enough you can see that we've got probably way too many queries in here so let's go ahead and ego load this and we'll just quickly talk about how we can't ego load collections it doesn't make sense so over on our discussion model for our latest post this is what we want to ego load at
06:55
the level of our controller so we're going to say discussion with latest post and user so now we can ego load the user for each of the latest posts give that a refresh and we are down to three queries so now regardless of however many discussions we have how many posts there are within discussions and how many different users there are it doesn't matter we're always going to end up
07:18
with three queries so let's just see why this is really important because it's really important to drill in why these kind of relationships are necessary if we bring back what we had before latest post and we just comment this one out really quickly and we say this posts and then sort by descending and then first we cannot ego load that why well we can ego load the posts in
07:48
but by the time we access this we are now dealing with a collection here so when we give this a refresh and actually pass in the created at date we give that a refresh we get an error here just because we are ego loading this which is the entire point really so if we go ahead and maybe just get rid of this for now and then we'll try to ego load posts in so we'll say discussion latest get give
08:14
that a refresh and your latest post must return a relationship instance again it's getting a lot more confusing because we're trying to access this like a relationship that's returning a collection when it's not it needs to be called as a method you can see we end up with five queries now what it could do is go over to the web root and say with posts dot user so load in all of the
08:37
users for all of the posts that we have and give that a refresh and that does work but as you can see we're in a little bit of a mess here so we've got ego loading posts that's fair enough but when we come over to our discussion we're returning this collection which can't be accessed like a relationship so we can't even perform any kind of real action on the latest post and it's just
08:59
slow as well because technically what we're doing here as well is loading in all posts into memory just imagine we've got three posts at the moment what if we had a thousand posts well we're loading a thousand posts into memory sorting them directly within php within that laravel collection and then just grabbing the first one it doesn't really make sense there are ways around this where
09:21
you wouldn't have to sort by descending you could actually sort at the ego loading level but again that just adds more complexity to your code so it's no surprise that we're going to go ahead and get rid of that and bring back what we have before things are a lot easier we know exactly what we're ego loading in we're ego loading the user for each of the latest posts we have a really clearly
09:43
defined relationship which we can do more with which we're going to be looking at soon and we can access this just like a standard relationship and there we go so a lot to think about there but these kind of relationships exist for a reason anything done at the database level is always going to be better than pulling in a huge collection sorting through them directly within your code
33 episodes4 hrs 18 mins

Overview

Eloquent is Laravel's ORM (Object Relational Mapper). In simple terms, it's how your models work with the database.

The good news? There's a bunch of powerful relationship types available. Our task is to learn when and where to use each one.

In this course, we'll cover each basic relationship type, how to access related models, and then insert, sync, update and delete related data. Oh, and we'll build a practical example for each relationship type, to really make it stick.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Comments

No comments, yet. Be the first to leave a comment.