تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Relationship Types Overview0:00

Let's talk about Eloquent, one relationship per episode. So I'm going to set up a little game plan here. I have a to-do plugin with Sublime. So we'll say Relations, and we'll tackle the one-to-one relationship today. But next we'll go over one-to-many. There's also a many-to-many relationship. There's a less common, but still appropriate in some cases, a has-many-through relationship. And then, of course, we have polymorphic relationships. Okay, so let's get started with one-to-one. Now one-to-one relationships are simple.

Defining One-to-One0:31

Okay, so let's get started with one-to-one. Now one-to-one relationships are simple. Think about a User. What is one thing that a User has? Well, you. You have an Address, right? You have a phone number. You have a profile. You might have, for something like Laracasts, you might have experience that is associated with your account.

You might have, for something like Laracast, you might have experience that is associated with your account. All of these are good examples of one-to-one relationships. A User has one, at least in our context, a User has one Address. Or a User has one Profile. Or a User has one set of Experience. Now compare that to a different relationship type, like a User's BlogPosts. Does a User have one BlogPost? No, they have many. So that's a different relationship altogether.

Adding Profile Relationship1:17

No, they have many. So that's a different relationship altogether. Okay, let's try this out. I'm in my User model, and I'm going to set up a new relationship to something that doesn't yet exist. We just have a base install of Laravel here. Let's go with that idea of a Profile. Well, we did say hasOne, and luckily, Laravel and Eloquent include all of these base relationships as readable methods. So I could say this->hasOne what?

as readable methods. So I could say this has one what? Well, let's say profile. Now again, notice profile does not yet exist. We're just establishing our desired relationship. Let's go ahead and create that. php artisan make:model Profile --migration. Okay, so that will create a Profile model and also give me a migration to go with it. So if I open up my app folder, here is our profile.

Okay, so that will create a Profile model and also give me a migration to go with it. So if I open up my app folder, here is our Profile. Next, let's go into database, migrations, and here is our new migration to build up a profiles table. Now let's be quick with this. We'll say a User maybe has a website. And how about, let's do this, a website_url, a github_url, maybe it's a developer site, and maybe also your twitter_url. Those are all things associated with a User's profile. Now you might be thinking to yourself, well, couldn't this just go on the users table instead?

Those are all things associated with a User's profile. Now you might be thinking to yourself, well, couldn't this just go on the users table instead? And the answer is maybe. That's an important thing to consider with this relationship type. Is it useful? Are you getting enough bang for your buck by taking these columns and moving them to their own table, or do they instead make more sense just being directly on User? We'll talk about that more in a minute. So now that I have a new profiles table, well, we still don't have a link between the profile and the User.

Linking via Foreign Key2:59

So now that I have a new profiles table, well, we still don't have a link between the profile and the user. This is what basic foreign keys are for. So let's say table, and let's do a integer for the associated user. Now for any given profile, we can link it up with a given user. Okay, so let's go ahead and migrate our database. And if I open up SQLPro, give this a refresh, we now have a users table that's empty, but also a new profiles table that we can associate with a given user. Let's very quickly just populate one here. A password should be encrypted.

Let's very quickly just populate one here. A password should be encrypted. I'm just going to do gibberish here. We'll set that manually later. And then we'll add our timestamps. Next I'm going to have a Profile. So for the userId column, we of course want to associate it with John Doe here. So we'll say 1, john.com. You get the basic idea here. Great.

You get the basic idea here. Great. All right, so now using basic SQL, we could fetch all users. SELECT * FROM the users table, and we'll get one. We could get all profiles, or we could even fetch the profile associated with John. So I could say WHERE user_id = 1, and of course we're going to get the same thing here, but only because we have one user and one profile. So we're going to use Eloquent to essentially reproduce this query. When we set up relationships like this, Eloquent will allow you to dynamically access, in this case the profile, as if it were a property, which means I could do things like this.

Accessing Relations in Tinker4:30

When we set up relationships like this, Eloquent will allow you to dynamically access, in this case the profile, as if it were a property, which means I could do things like this. Give me the user's profile, and instantly it will be as if I had an instance of this given profile, but scoped to the given user. So if I wanted the GitHub URL, I could do something along the lines of this. Let's see it in action. I'm going to boot at php artisan tinker so that we can play around. I'm then going to find the only User in our system, which is John Doe. And because we have this relationship in place, I can now say user, give me the profile. Now again, because we have a hasOne relationship, this is important, that dictates what foreign

And because we have this relationship in place, I can now say user, give me the profile. Now again, because we have a hasOne relationship, this is important, that dictates what foreign key we're using, what ID we're using here, essentially what SQL query will be executed behind the scenes. Because when we run this, Laravel and Eloquent will run the necessary query, fill up the attributes, and then make them available to you. So once again, I could say user, profile, and give me the GitHub URL, and there we go. If you want to see this in better detail, let's use the DB facade to var_dump all of the SQL queries being executed in real time. So let's say, give me the SQL and then also the bindings.

the SQL queries being executed in real time. So let's say, give me the SQL and then also the bindings. So let's run that. And now, once again, let's find our User, and you'll see we instantly get our query as well as the bindings. In this case, there are no bindings, so we have an empty array. But we did select all from users, and in this case, we just grabbed the first one in the bunch. Now let's get a profile, and we'll do another query. So this is what's being run behind the scenes.

Now let's get a Profile, and we'll do another query. So this is what's being run behind the scenes. Let's take a look. SELECT * FROM profiles WHERE user_id = ? matches the ID of our current User. And again, Laravel's going to do that behind the scenes for us. It'll automatically attach those bindings. Now at the end of it, we're just making sure user_id is not null. But if you see this right here, it's basically what we had earlier. SELECT * FROM profiles WHERE user_id = ? matches up. Now actually, let me show you one more thing.

Select all records from the profiles table where the user ID matches up. Now actually, let me show you one more thing. Let me exit and restart. All right, so a moment ago, we listened for any SQL queries and we dumped them. But we could also do this another way. It might be a little more intuitive for you. Again, you wouldn't do this in production. It's only for your testing and for experimentation. Anyways, I'm going to say enableQueryLog. Next, I'll find a User like we did before.

Anyways, I'm going to say enableQueryLog. Next, I'll find a User like we did before. But this time, you won't see anything. That's okay. Let's do one more query. Let's get the user's profile. So at this point, we know there should have been two different queries. Okay, let's say DB::getQueryLog(). Now you can see we have an array of all of the queries that have been executed. So our first one is where we grabbed one User.

Now you can see we have an array of all of the queries that have been executed. So our first one is where we grabbed one User. It took 2.08 milliseconds. The next one was where we found the Profile associated with the User. So as you're working along with this series, if you ever get a little confused, enable the query log, run the necessary code, and then if you need to, you can debug the SQL query to see where things have gone wrong. All right, let's review one more example. So we've decided a User does have a Profile. But now let's maybe do another one.

Second Example: Experience7:44

So we've decided a User does have a profile. But now let's maybe do another one. And this will be an example of where you should ask yourself if it's necessary or not, but we'll do it in two steps. So I did say maybe a User has Experience. So on LayerCast, as you know, as you may or may not know actually, as you watch videos or participate in the forum, you earn points. Mostly for fun, just an identifier for how active you are on the site. So one way you might represent this is through a hasOne relationship. You could say hasOne Experience.

So one way you might represent this is through a hasOne relationship. You could say hasOne Experience. Okay, once again, let's build up a model for the User's Experience and add the migration as well. So now I will switch over to that. Now in this case, it's assuming the table name is experiences. We still might want to stick with something like that, but I'm going to leave it as it is so we can continue with the defaults. Anyways, if we're thinking about it, we may just be storing the number of points, right?

Anyways, if we're thinking about it, we may just be storing the number of points, right? So we could do this. All right, and then we run our migration. So now, if we take a look at our database here and give this a refresh, we have a User named John. And John has a profile, but he also has experience. But you'll notice, once again, we've fallen into this trap where there's no way to connect a given record here. So let's say we have 145 points.

we've fallen into this trap where there's no way to connect a given record here. So let's say we have 145 points. Well, 145 points for who? We always need to associate it with a User. So we'll switch back and we'll say, once again, we have a relationship here. Okay, so I'm going to roll back the previous migration and then rerun this migration. Okay, so if we come back, give it yet another refresh. Now I could say, the User with an ID of 1 has 145 points. Let's give it a shot.

Now I could say, the User with an ID of 1 has 145 points. Let's give it a shot. php artisan tinker. We'll find our user, and then we'll say user experience. And now we have that entry. So we could say, if you want the user's experience points, you could use this syntax here. One more time, let's boot this up and view the queries. So enable query log. And now I'm going to hit up to cycle through my previous commands.

So enable query log. And now I'm going to hit up to cycle through my previous commands. So fetch a User, and then grab their experience. Okay, now let's get the query log, and that will spit out two queries that we can review, again, if we're debugging and we're trying to figure out what exactly is happening behind the scenes. It's good during the learning stage. Okay, so is that fine? Sure, everything boils down to decisions. But in this case, if this is the only thing I will ever track in terms of

Sure, everything boils down to decisions. But in this case, if this is the only thing I will ever track in terms of experience, you need to ask yourself, are we getting much bang for our buck by having points on this experiences table? Or would it be just as easy to add it to the users table? These are the questions to ask. So I might do this instead. Now, if we do php artisan migrate:fresh, that's going to drop all of the tables and build them up again. If we switch back, yeah, now,

that's going to drop all of the tables and build them up again. If we switch back, yeah, now, if you don't want that experiences table there, we've decided you don't need it. Okay, just delete it or remove the PHP migration class. And now here, when you build up your User, you can store the experiencePoints directly on User. Again, in these situations, it's often a case where there's not necessarily a right or wrong, it just depends on a few different factors. All right, so that will do it for your first relationship. Let's go to our tasks.

All right, so that will do it for your first relationship. Let's go to our tasks. We have completed this one. In the next episode, we will review the oneToMany relationship.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟