Finding Records in Tinker0:00
All right, so this is exciting. Why don't we start, I'm gonna boot up php artisan tinker, by the way. Why don't we start with a simple method call, but we're gonna review it at a deeper level. And that's simply the process of finding a record. So in the previous episode, we created a Post model and seeded the table. So if I were to say, Post::all(), and if we run that,
So if I were to say, at Post all, and if we run that, you'll see that we have tons of rows here. And it looks like this started with an ID of 151. So if we wanted to find this exact Post, well, let's use at Post, and then we could say Post::find, and then we provide an ID. But on that note, did you also know that you could pass an array?
But on that note, did you also know that you could pass an array? So you could say Post::find, and then if I say 151 and 152, well, behind the scenes, Laravel can detect that and know, okay, you're trying to find multiple things. So rather than returning a model instance to you, I'll give you a Collection instead. So if we run that, now we do in fact have a Collection
Tracing Static find Call1:03
So if we run that, now we do in fact have a collection that we can sift through. All right, so like I said, this is basic stuff, right? This is the first thing you learn how to do with Eloquent. But what I wanna do in this episode is figure out, well, what exactly is happening behind the scenes when I call that static method? Well, let's dive in and see.
when I call that static method? Well, let's dive in and see. If I switch back to my editor, well, let's just start with the Post model, right? And we don't see any kind of find method here, which means of course it's declared on the parent class that we extend. So if we hunt that down, let's see what in fact is going on here. So it looks like we create a new instance
let's see what in fact is going on here. So it looks like we create a new instance because we are in fact calling a static method while we have no real instance yet. So we set one up, create a new model. And then we have a quick little check just to see if an empty array was provided. And if so, we're just gonna give a new collection and bring it right back to the User. Otherwise, look what we are doing here.
and bring it right back to the User. Otherwise, look what we are doing here. We take our model instance and we're calling this newQuery method. And then we call a find method on whatever is returned from that. So it looks like when we call Post::find, well, that static method there isn't really doing any of the legwork. It's just sort of like a toll booth.
Creating the Query Builder2:21
isn't really doing any of the legwork. It's just sort of like a toll booth. It's something that gets you from here to there. All right, so that means, well, what exactly is happening when we set up a new query? Well, we do two things here. We get our builder instance. So if we take a look at that, well, we create a new EloquentBuilder. And you can see that just returns a new instance.
well, we create a new EloquentBuilder. And you can see that just returns a new instance of this builder class. If I scroll up, Illuminate\Database\EloquentBuilder. Now, you'll find that this in fact is the class where you will see things like find or where, or any other number of things that you often reference, like delete. Now, we're gonna talk more in a future episode about how some of these methods on the builder class
Now, we're gonna talk more in a future episode about how some of these methods on the Builder class get called dynamically when you reference a static method on your model. But for now, I don't wanna get too far off track from what we're interested in. So let's come back to our find method and start over. It really helps me if I go a ways and then when it gets blurry, I just go back and start over.
and then when it gets blurry, I just go back and start over and try to understand it again. So we call Post::find, we create a new instance, and then we set up a new query and we call a find method on that builder class. Right here, we set up a new query without scopes and then we apply any global scopes. You might've learned about this in Laravel.
Applying Global Scopes3:43
and then we apply any global scopes. You might've learned about this in Laravel. You can create a class where you register a scope that will be applied to every single query. So if you've ever had a situation where you think, well, really every single time I run this query, I want this constraint or this where clause to be in place. If that's the case, then you want a global scope. And this is where Laravel actually applies those. So that's good to know.
And this is where Laravel actually applies those. So that's good to know. But anyways, if we set up our new query without the scopes, well, we create our new Builder class. Remember that method is just a pointer to new Builder. And then we pass to it our queryBuilder. And that's actually the class where these queries are built up. And that's why we call it the queryBuilder. And you'll see right here,
And that's why we call it the query builder. And you'll see right here, we get some things like the connection and the grammar. Don't get too distracted by that. The main thing is we create a new instance of Illuminate\Database\Query\Builder. And now don't let this confuse you. This is something that was actually hard for me when I was first digging into this stuff. We have two different builder classes here.
Eloquent vs Query Builder4:48
when I was first digging into this stuff. We have two different builder classes here. So if we go to the last one right here, Illuminate\Database\Eloquent\Builder, but then we have the query builder itself, which is a totally different class. And it was hard for me to wrap my mind around that when I was first trying to figure out what exactly is going on here. And further, what can be confusing
what exactly is going on here. And further, what can be confusing is you'll see the same methods in both places. So for example, here's the query builder. And this is where you see things like join or where, or whereIn, or whereRaw. So all of these methods, like when you're using the fluent interface, post join that table, and then add a further where clause,
post join that table, and then add a further where clause, all of that stuff is ultimately being triggered here where we build up the query. So that means, well, on the other Builder class, what exactly is happening? Because remember, if we return to the find method, let's start over again. We call Post::find. We set up a new query
We call post find. We set up a new query where we create a new Eloquent builder class and we pass to it a dependency of the query builder. Okay, so let's take a look at that. Notice the query builder is being passed through right here and it's saved on a query property. So now, if you remember, we ultimately call a find method on the Eloquent builder class.
we ultimately call a find method on the Eloquent builder class. So if we take a look at that, when we say Post::find, this method is going to be triggered. And if we look, once again, we check to see if the $user passed an array to the find method, like we did at the beginning of the video. And if so, we're gonna find many items.
like we did at the beginning of the video. And if so, we're gonna find many items. Otherwise, take a look. We're just deferring to methods on the query builder. So here's what's cool. When you call these helpful methods like find, well, behind the scenes, you can see it's just doing a basic where clause. It's just saying query where the ID is equal to what they passed in.
It's just saying query where the ID is equal to what they passed in. And then right here, get the first result. So this probably looks like stuff you've written countless times. And further, when you say Post where ID equals this, grab the first one, well, you're starting to see what's happening behind the scenes. The actual model class isn't doing tons of work.
Recreating find Manually7:07
what's happening behind the scenes. The actual model class isn't doing tons of work. It's just deferring to the Eloquent builder class. And this is where we build up our query. So with all of this in mind, why don't we try this out for fun? I'm gonna switch back to the terminal. We wanna fetch this for a 151 without using that finds method. And it's not like you would ever do this for real.
without using that find method. And it's not like you would ever do this for real. We're just doing it so we understand a little more what's happening. Okay, so I'm gonna create a new Post. And now can you remember what the next step would be here to fetch a record? Well, let's just return to it. Let's go to the model, find, and remember we called newQuery.
Let's go to the model, find, and remember we called newQuery. So I could say post, I want a newQuery here. And now I can call any methods on the Builder class because when you call newQuery, all you're getting is an instance of the Eloquent Builder. So you can call any methods that are defined here. And in many cases, like we talked about, these methods are just deferring to methods on the QueryBuilder itself.
these methods are just deferring to methods on the query builder itself. And don't worry, we'll dig into the actual functionality in the query builder in its own lesson because there's a lot to talk about there. Okay, so anyways, if I return, I could say find(151), and we're gonna get the exact same thing. But further, well, if we take a look at that find method, what we realized is it's just a little sugar,
But further, well, if we take a look at that find method, what we realized is it's just a little sugar, like I often call it, that defers to a where clause. So we could instead say Post::newQuery()->where(id, '=', 151)->first(); That's exactly what's happening when we run Post::find(151). But of course, it's far more intuitive to use something like this versus that. And of course, don't forget,
