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

Introducing One-to-Many0:00

At this point, we're fairly comfortable with one-to-one relationships, but the truth is you won't reach for them too often. But a one-to-many relationship, on the other hand, is another story. You're going to reach for this all the time. So think about it. Let's go to User. What are some things that might represent a one-to-many relationship? Alright, well, what are some things that a User can have many of? Well, very easy. An infinite number of things.

Well, very easy. An infinite number of things. A User can have many Posts. Maybe you have a blog and you want to say, give me all the Posts that have been created by this User. That is a one-to-many relationship. One User can have many blog Posts. What else? Well, maybe a User can have many jobs. What else?

Well, maybe a User can have many Jobs. What else? A User can have many Achievements, maybe things they accomplish on your site. When they finish this Project or they complete that task, they are awarded an Achievement badge. Alright, a User can have many Achievements. Now it's not just related to User. So an example of blog Posts, well, a Post can have many Comments. Or just one more, maybe. A Project can have many Tasks.

Defining User-Posts Relationship1:11

Or just one more, maybe. A Project can have many Tasks. You get the idea. All of these are good examples of one-to-many relationships. So let's try it out. Let's pick any of these. How about this one to start? A User can have many Posts. Alright, well, we'll just take this right here. It's nice and readable.

Creating Posts Model Migration1:27

Alright, well, we'll just take this right here. It's nice and readable. Instead of hasOne, we do hasMany. This actually comes from the Rails world. They use a similar convention and I think it works great. So a User can have many blog posts. So once again, this relationship doesn't exist. We don't have a post table. Why don't we do that really quickly? php artisan make:model Post -m and I do need a migration as part of that.

Why don't we do that really quickly? php artisan make:model Post --migration and I do need a migration as part of that. Alright, so if we go to our posts table, well, to begin, a Post belongs to somebody, right? So unsigned integer, user_id. And notice I said belongs to. That's another kind of relationship. If a User has many Posts, then a single Post belongs to a User. We'll talk about that more soon. So what else might we need? Maybe basic string for the title and then maybe a text column for the body of the Post.

So what else might we need? Maybe basic string for the title and then maybe a text column for the body of the post. And let's keep it very simple like that for now. Okay, so if I migrate my database and if I switch over to SQL Pro, we now among the other tables from the last episode, we have a new table for posts. And again, each one can be linked to a given User through that column. So let's try this out. Let's go to users. We don't have any User at the moment. I could hard code one like we did in the last episode or we can use a model factory.

Generating Data with Factories2:43

We don't have any User at the moment. I could hard code one like we did in the last episode or we can use a model factory. So I could say factory for a User and create one. So that's going to read a blueprint. I'll show you that in a minute. We have an issue. Oh, yeah, that's right. So in the last episode, we toyed around with this idea of whether to represent a hasOne relationship as a new table or when it makes sense to just add another column to your users table in this case.

relationship as a new table or when it makes sense to just add another column to your users table in this case. So the issue is it's blowing up because we're not we're not accounting for experience points. No problem. We're going to go into our database directory into factories and in the user factory here, you'll see there's no reference to experience points. So the operation is blowing up. So in this case, it's superfluous. But nonetheless, we'll just add that there and give it another try. OK, so now we have a new we give this a refresh, a new user in our system named Flow.

But nonetheless, we'll just add that there and give it another try. OK, so now we have a new user in our system named Flow. All right. Next, I'm going to whip up a Post. So once again, we could do this using a database factory. And more often than not, I use factories almost exclusively for testing. But if you want, you can also use them for basic database seeding. So if we want to create a PostFactory, we could do that like so. php artisan. And you'll see there is a make:factory command.

php artisan. And you'll see there is a make:factory command. So let's run it. php artisan make:factory for a Post. And I'm also going to specify the name of the model here. All right. So now if we switch back, we have a new file here. So think of this as a way to define the blueprint for what a Post might look like. You can use this when writing your tests. So imagine a test that says, well, given I have a couple posts and when the User does

You can use this when writing your tests. So imagine a test that says, well, given I have a couple Posts and when the User does yada, yada, then I expect to see this. All right. That given section where we need to assume that a couple Posts exist, well, you can use this blueprint or this model factory to whip that up. But again, you can also use it for basic database seeding or like we're doing in this lesson where you just want to quickly whip up a User or a Post. All of those are valid uses. OK.

All of those are valid uses. OK. So we have a title and we have this faker object that allows us to quickly whip up generic data. So I could say, give me a fake sentence. Next, we need the body and that will be a fake paragraph. Or let's just do a sentence again. And then finally, a Post belongs to a User. So let's accept the function. And here we can whip up a brand new User.

So let's accept the function. And here we can whip up a brand new User. All right. So does that all make sense? When I whip up a Post, we need a User. And if we don't provide a user_id column, it's just going to scaffold a new User, save it to the database, and then fetch the ID column and return that. OK. So let's give it a shot. Let's now boot up php artisan tinker and say I need a factory for a Post.

So let's give it a shot. Let's now boot up php artisan tinker and say I need a factory for a Post. Now notice user_id of three. So in this case, we didn't tell it which User to associate with that Post. So if we give this a refresh, it just whipped up a brand new User on the fly. And if we take a look, there is the User it created. We could also override that, though. I could say, well, the user_id is going to be flow, so two. Now when we do it, it won't call that function and it won't scaffold a new User, as you see there.

Querying Related Posts6:07

Now when we do it, it won't call that function and it won't scaffold a new User, as you see there. So give it a refresh. We have our User here, and we have a new Post associated with that User. All right. Great. So just a quick recap for you. Anyhow, if we go back to our User model and we scroll down, I still need to fetch all of the Posts that are associated with User. If User can create many blog posts, then we want to make sure we have a relationship for

of the Posts that are associated with User. If Flow can create many blog posts, then we want to make sure we have a relationship for that. Then you could imagine an endpoint, a URI endpoint, like posts for Flow or users flow posts, giving all the Posts associated with Flow. And behind the scenes, all you're going to do is find Flow using a basic database query, and you're going to fetch flows posts. All right. So let's give it a shot. Once again, we'll begin with a basic database query.

So let's give it a shot. Once again, we'll begin with a basic database query. flow has a userId of two. So we're going to select all from posts where the userId is two. And now we can see flow has created exactly one post. Now let's do it with Eloquent. I'm going to boot up php artisan tinker. I'm going to find flow. There we go. And now I'll say user or flow, give me your posts.

There we go. And now I'll say User or Flow, give me your posts. So once again, we create that relationship, which then allows us to access it dynamically as if it were a property. And behind the scenes, it's going to essentially do this exact same query. Now if you want to see that in action, let's do what we did in the previous episode. Let's enable the query log. Let's find Flow. Get Flow's posts. And then finally, we'll get the query log and review the results.

Get flows posts. And then finally, we'll get the query log and review the results. All right. So we have a total of two queries. The first one is where we fetch the User with an ID of two. And then to fetch flows posts, we select it all from posts where the postUserId is equal to two. And if we switch back, exactly that. So this is the convenience that Eloquent provides you. You can represent this with a basic relationship.

Overriding Foreign Key Defaults8:11

So this is the convenience that Eloquent provides you. You can represent this with a basic relationship. And as long as you're following sensible defaults, Eloquent will reach for the proper foreign key names and things like that. But again, if you ever need to override it, like let's say, well, by default, Post is going to look for a user_id key. And that's because we're in the User class. So Laravel and Eloquent will choose a sensible default. That almost always will be true. But maybe you have like person_id or something.

That almost always will be true. But maybe you have like personId or something. You have a slightly different database setup. Okay. Let's see what that looks like. Boot it up again. Build a query log, find the User, get the User's posts, and it blows up. So notice right here is the query, and we don't have that. We have a userId column. So that's just to show you if you ever have something that's different from the norm,

We have a user_id column. So that's just to show you if you ever have something that's different from the norm, let's go to posts, like rather than user_id, you have person_id or user's_id, something that goes against the norm, you can override that. And of course, when in doubt, go to the source. So take a look at the hasMany relationship, and we can see here are the arguments it accepts or the parameters, the related table, what is the foreign key name, and then what is the local key name. And the local key name is just whatever the primary key would normally be. So that means if we ever need to fetch a user's, let's do some of the other ones.

And the local key name is just whatever the primary key would normally be. So that means if we ever need to fetch a User's, let's do some of the other ones. All right. Jobs. And then you could construct this behind the scenes. Exact same thing. If a User has many Tasks, you could do that as well. If each Task is associated and created by a given User, that would make perfect sense. What else? User has many Achievements.

What else? User has many Achievements. Now this one, well, you could make it work. So I'm being a little misleading here. So we could do something like this. But let's think about it. You have an Achievement. Let's say an Achievement would be that you read your first blog post, right? Well, on that achievements table, you would have some kind of Achievement with a name of read first blog post, right?

Well, on that achievements table, you would have some kind of achievement with a name of read first blog post, right? But it's also going to expect a user ID. What is the User associated with this achievement? However, is that quite right? I mean, you can make it work if you want, but it sounds to me like an achievement like that could be applied to many different users. Or in reverse, any number of users could acquire an achievement like this. So in that example, if you want, you can make this work, but instead you might want to reach for a different relationship type altogether.

So in that example, if you want, you can make this work, but instead you might want to reach for a different relationship type altogether. And we'll talk about that in the next lesson when we discuss many-to-many relationships.

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