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
30. Using has one through relationships

Episodes

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

Transcript

00:00
A has-one-through relationship works in pretty much the same way as a has-many-through relationship, which we've already covered.
00:08
But we're going to look at a slightly different example in this episode and set things up slightly differently. So the example that we're rolling with here is that users have many referral codes, but then if we want to access the referrals on their own, we want to get the user through that referral. So by that, I mean each referral is not going to store the user who owns that referral.
00:33
It's just going to be on its own. We're going to fetch the user via the intermediate referral code that's stored on that referral. So if that doesn't make any sense at all, absolutely fine. Let's go ahead and set our database up just so we can see what we're doing.
00:48
And then we'll go ahead and figure out how to solve this with a has-one-through relationship. Okay, so we already have migrated everything. We've got a fresh layer of our project set up here. Of course, we don't have any other tables in the database.
01:02
We're going to go ahead and first of all just generate a couple of fake users. So we're just going to use a couple of users to test this. So let's go ahead and use phpArtisanTinker and we'll go ahead and use our trustee user factory here and we'll go ahead and generate two users here out in the database.
01:18
Great, so we've got two users that we can work with. Okay, so our users have many referral codes. So let's go ahead and make out a model called referral code and let's create a migration alongside of that
01:31
and we'll fill this in first of all before we do anything else. So create referral codes table. So each of our users will be given many referral codes that they can send to people. So for this we obviously need a foreign ID hooked up to the user.
01:45
So we know who owns these codes and then we're just going to have a really simple string on here with the code itself. So that's how simple we're going to keep this. So we'll go ahead and migrate this really quickly.
01:56
So phpArtisanMigrate and let's fill in a couple of these and obviously we would generate these or allow users to generate these on our UI. So we'll hook one code up here with ABC to our first user and then we'll hook a second code up to our second user with obviously a different code.
02:14
So let's save that out and there we go. So each of the two users in our app now have a referral code each. So now we want to create out the actual referral. So when this referral comes through we're going to create a referral record in the database
02:28
matched up to that referral code and then we can have any kind of metadata on this model like the commission that's going to be made or whatever else we need to store. It doesn't really matter too much at the moment.
02:39
So we're going to go ahead and make a referral model out and let's go ahead and fill in the migration for this and for this we're not going to store the user itself. We're just going to store the reference to the code.
02:52
So we're going to say table and we'll say a foreign ID in here. Now using Laravel convention this would now be referral code ID. So referral underscore code ID and that's pretty much what we need. Now, like I said, we can add any kind of metadata to this.
03:07
So let's go ahead and use an integer here for the commission that is going to be made for this. Although it doesn't really matter for this example. Okay, let's go ahead and run phpArtisan migrate and we're done. So we're going to fill this in manually in the database,
03:19
but just imagine when a referral code comes through we're going to look that up, insert that referral code in here, calculate the commission that that person is going to have made and we are done. So we can do the same thing here for that second user
03:34
and just add a slightly different amount in there as well. Okay, great. So we've got two referrals and let's just imagine that as an admin in our app, we want to look at all of the referrals that are happening within our application.
03:48
We want to show the commission, the code that was used and of course we want to show the user, but in the way that we've set our database up or if we're using a legacy database that does not have that information in there,
03:59
we don't have a user attached to this referral. So what we're going to do is figure out how we can use our has one through relationship to solve this. So I'm going to go ahead and create out an admin referrals endpoint just here and we'll go ahead and return a view here just so we can visually see this data.
04:18
So let's call this referrals and index and we'll just go ahead and pass down all the referrals from our app. So we'll just say referral and let's scope these by latest and let's grab all of them. Okay, we'll go over and create out our view in here.
04:33
So referrals and inside of here index.blade.php and we don't have any at the moment. Let's just dump our referrals out on the page and let's go over of course to admin referrals and there they are.
04:48
Okay, so we'll iterate through these. We'll go ahead and check out how we can access this user and then we'll take a look at eager loading of course just to make sure everything is running nicely. So we're going to go ahead and say for each referrals as referral and we'll end that for each just there
05:03
and then inside of here just a div we'll do with the referral ID maybe and we'll go ahead and add the name in there and then you can obviously access the commission if you need to. So we've got two referrals. We need to access the name of the user.
05:17
So let's think about this over in our referral model. Remember this doesn't have any access to the user. So when we looked at our has many through relationship, this was pretty straightforward. We didn't need to specify any columns.
05:31
We had the method set up so we could use that nice syntactic sugar on top of this. Let's just try this now and just see what happens when we try and access a user using this relationship and the error that we might get. So we're going to go ahead and of course use the has one through relationship type.
05:51
So we know that a referral has a user through the referral code that is stored on the referral. So that should work right? Well, let's go ahead and try this out. So we're going to go ahead and access the referral user and we know that users have things like names so we can just grab the name out.
06:13
Let's give that a refresh and see what happens. Okay, so we are going against Laravel conventions here in terms of how we want to access this data. That isn't a problem because Laravel as we've already seen allows us to define the keys that we want to use in order to map this data up.
06:30
But at the moment what this is looking for is it's looking for a referral code ID on the users table. That doesn't exist. So we're kind of going backwards here. Normally this would be a belongs to relationship because if we think about it on the referral the referral code belongs to this.
06:48
So we need to do a little bit of work here to figure out the keys that we need to specify in order to hook this up. So what we're going to do is start to provide in these extra keys just to give us an idea about how these work. Okay, so the first key here is going to relate to the user.
07:04
We can demonstrate this by typing in something silly and heading over and giving this a refresh and notice well nothing happens, but we'll see this in action in just a second. We can do the same thing for each of these. So I tend to do this if I'm trying to figure out what is happening where.
07:19
So let's just put X and we'll put Z in there. If we give this a refresh you can see referral codes.z does not exist. So Z is obviously referring to referral codes. The first key here relates to the user. The second relates to the referral code
07:33
and then these two relate to the foreign keys. So let's just follow this through and go ahead and add this in. So the first key for the user is ID. The second key for the referral code is ID. The local key here we look over on our referrals is the referral code ID.
07:50
So let's go ahead and add that in there now and the second local key is the user ID. So let's go over and give that a refresh and there we go. That is all hooked up. So this is kind of mostly trial and error of what you're hooking up
08:07
and how your database is structured. You don't necessarily have to learn these. I'd recommend just playing around with them, but that is now hooked up nicely. Notice that if we kind of change these around, so referral code ID, that's going to give us obviously referral codes.
08:23
Referral code ID doesn't exist. So we know that this is looking for that user on the referral codes table. So let's switch them back around and give this a refresh. Okay, so there we go. That is nicely hooked up.
08:35
We've got the user for each of these and of course if we change these around, so if we change around the referrals and both have these set to the first referral code, sure enough, we get the same user for each one. Okay, so I'm going to go and switch that back over to the second one
08:52
and we're going to go ahead and just add a little bit more to this. So we're going to access the referral code itself. So for the referral, we know that we have a referral code. So let's go ahead and add in the referral code relationship here.
09:05
Now, if we think about this, a referral code belongs to a referral. So we can introduce a pretty simple relationship in here. So belongs to referral and that should work nicely. And yeah, that needs to be referral code and we should be good.
09:20
So now we can head over to our index page here and just pop that in the middle. So let's say referral, referral code and then the code of that referral code. Give that a refresh and there we go. We see the code. We see the user despite the fact that all of these three things have been split up.
09:40
Let's go ahead and just make sure that everything is looking good in terms of our queries. So I'm going to go ahead and put in Laravel Debug Bar as we have multiple times throughout the course. Give this a refresh and take a look at the queries. Now immediately for just looping through two records, five queries seems like a lot.
09:57
We can check specifically if we have an N plus one problem by going ahead and just duplicating this and adding in a new user or generating a new user with our factory. And I'm going to go ahead and generate a new referral code in here for this user. So let's say XYZ, fill in our data in here and let's create our new referral just to see what's going on.
10:20
So let's create a new referral in here with that specific referral code. Go ahead and give in the commission pence and we should see these queries jump up to seven. Great. So we have an N plus one problem and we can go ahead and fix this. Okay, so let's think about what we're doing here.
10:37
We'll go over to our web routes over in our referrals where we're getting our referrals here. We want to go ahead and eager load in the referral codes because of course they come from a belongs to relationship to our referral codes. So let's go ahead and say with referral code.
10:53
So let's double check that method name. Yep, that's good. So let's go ahead and give that a refresh. We are down to five. But of course, as you can see here, we're now looking up the user that's coming through that referral code for each of these.
11:07
So if we were to add another one of these, we would, of course, end up with six queries fetching a new user every single time, which is not what we want. So what we can do here is just go ahead and eager load this as normal. So we can eager load this user in like so,
11:22
even though we have created this kind of backwards relationship here, give that a refresh and we are down to three queries. We are eager loading in all the referral codes that we need to display these referrals on the page and we are eager loading in all of them users with that through for each of the referrals that we have on the page as well.
11:39
So now every time we add a new referral, we're still going to end up with just three queries. So the eager loading here, despite the fact that we have this kind of odd relationship going back to the user via referral, still works really nicely.
11:54
Now, you might have noticed here that what we could actually do is we could access the referral code and we can actually access the user through that referral code as well. Let me just show you an example of this, because although this is a really simple example, it just goes to show that you can simplify things even when you have examples like this.
12:14
So we know that we have access to the referral code via this referral, but we've set up this complex relationship to access the user just over here through the referral code, which we already have access to. There's nothing wrong with doing this because you might need to access this relationship in a relationship type way to update the user.
12:34
And I'll show you that in a second. But let me just show you what I mean. So if we come over to our index page here, instead of doing this, I'm just going to cut this out just for now. What we could do, because we have access to the referral code, we can access the user through that referral code. So we can say user and name and that's still going to work.
12:53
If we give that a refresh and just make sure we actually set up the relationship. So let's go over to our referral code and create a relationship out here for that user. So this belongs to a user. Like so. We should see exactly the same thing.
13:13
OK, so it works in exactly the same way. Now, we've still got an N plus one problem here because we have to slightly differently egoload this. So let's just go ahead and say referral code dot user like so. Give that a refresh and we end up with obviously just three queries again.
13:31
So we could do that. But by the way that we have set this up like so and having we just come back over to our referral by having this relationship, it means we have direct access to the user in a much more convenient way. If we just needed to access the user at any point in our app, even in our templates or just within our code, we have a direct access to our relationship for our user now, and that makes a lot more sense.
13:58
So let's go ahead and just get things back to the way they were with accessing this like this. We should still end up with three queries. And let's just take a look at how we might access this directly within code. So we'll just do this up here to play around. So let's go ahead and access a referral. So we'll just find one by its ID. Let's go over to our referrals.
14:22
We'll just say find one. Now we know that we can access the user directly through there. So if we just give that a refresh, we have access to that user. If we hadn't set that relationship up, we would have to go into our referral code, then into our user, and then potentially do something with them.
14:39
So although we get the same result, we have a nice shortcut to the user here, which we could use to even update the user if we needed to. So let's go ahead and update the user's name here to updated name. And you just see how easy that is. Give that a refresh.
14:54
We get one back because that tells us that one row has been affected and that user has now been updated. So adding these methods in, although they're not strictly necessary because you can access them through other relationships that you have set up, is a lot more convenient. First of all, for the speed of doing things,
15:12
you don't need to go into the referral code to fetch the user and then update them. You have direct access to them. And second of all, just because your code reads a lot better, we have access to a referral and it's clear that we are accessing the user who has that referral, who's responsible for that referral, and then we're going ahead and doing something with them.
15:33
So although we're not going to be doing that in this example, and we're just looking at listing through these, that is the benefit of having something like a has one through relationship. Couple of benefits there. So that is how we deal with has one through relationships in a slightly different way, setting this up so we're trying to access a user who belongs to something, but via something else.
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!

Episode discussion

No comments, yet. Be the first!