3.2 Query Scopes
It's common to reuse a query multiple times throughout an application, and query scopes make it easy to do just that. You'll learn how to write them in this lesson.
1.Introduction1 lesson, 01:29
2.The Basics3 lessons, 40:56
3.Using Eloquent5 lessons, 53:38
4.Relationships2 lessons, 26:36
5.Conclusion1 lesson, 00:59
3.2 Query Scopes
In the previous lesson we looked at Tinker which is a really really cool feature that allows us to well tinker with our data. And then we looked at our model classes and how we can use them to query the database we use the fine method to find records based upon the primary key. And we also use the query builder to build a query to find records based upon a particular condition. Well what we're going to look at in this lesson is called query scopes. And it solves a very specific problem, and it's just one way of solving this problem but let's first of all fire up Tinker. So artisan Tinker. And the problem is this. Let's say that we have a query that we use throughout our application, and that is one where we find the guitars that are older than a given year. So in one part of our application, we would find all of the guitars that are less than 1980. And so, we would run that query and then we would get those guitars. But then in another place in our application, we would retrieve all of the guitars that are less than 1977. And we might have some other part of our application where we find the guitars older than the current year, this is a very common query that we use throughout our application. And just about every applications has one of these types of queries. Well, the problem comes whenever we need to modify. All these queries. Not just the year that we were specifying, but we need to make some changes to the query itself. Well us being humans, we're going to find, most of them, but there's going to be a couple that we forget to do. And so, then we get to play the game of, why does this work here and why does it not work here. Well the query scopes solve this particular problem. It allows us to easily reuse query logic in our models, and all we have to do is write a method in our model class. So we're going to go to the guitar class, and we're going to add a method here. We're going to say function, and scopes are named very specifically. They begin with the name scope. If they don't, then they aren't considered a scope. But after that, we have a name that is descriptive as to what this query is for. So we could say that this is for finding guitars older than a given year. Now a scope takes at least one argument. It's called query. This is going to be injected by eloquent and this is the query builder object. So that inside of our function we will use this query object to build our query. So we would say query where and then year is less than the given year. We need the given year. And that is gonna be the second argument. Whatever we call this scope function, we aren't going to use the term scope and we aren't going to pass in the query. Instead you'll see what we do. So we'll say as long as the year is less than the given year then that's what we want. So let's go back and let's use this. So we do so by saying App\Guitar and then olderThan. We don't say scope, and whenever we specify the year we don't pass in the query builder. That's automatically done for us. All we have to do is just pass in the data that we need for this query to work. Now, whenever I execute this, we're going to see that there is a bad method call exception. It says that the olderThan method does not exist. So, here's the thing about Tinker. Whenever we start it up it is running within the scope of our project at that given time. So any change that we make to, like our guitar model, in this case. The guitar class inside this session of Tinker does not have that method. But that's easily fixed, we just need to stop Tinker and start it back up. And there we go, so now we can say App\Guitar older than. And let's find the guitars older than 1980. And we can see that now we get this builder object. So we can call the gets method and we get to those guitars. And we can do basically anything that we wanted to here. So if we wanted to return the guitars ordered by the descending year. Then we could do that. So we could say year, descending. Or let's do ascending. That makes a little bit more sense in this case. Although we do need the orderBy method, don't we? So orderBy, year, ascending. Now since we made a change to that method, we need to stop Tinker. And start it back up again. But now we can say, App\Guitar olderThan 1980, and we would get our guitars older than 1980, and they will be ordered by year ascending. So now we can use this method any time that we wanted to find a guitar that is older than a given year. But we can also use this and build upon it so that if we wanted to find all of the guitars that would be considered vintage guitars, well, we could use this scope that we have defined. Because the term vintage is really a moving target it's based upon the current year. It's 2017. If we just say that our vintage guitars are going to be at least 40 years and older then we could take the current year minus 40, and then that would be the starting point for our vintage guitars. Here we can say function and then getVintageGuitars. Now this is not going to be a query scope, this is just a normal method, we aren't going to accept any information here. So instead, what we do is we say $this. That we're going to still use our olderThan method, just like we did in the command line here. We say $this, and then olderThan, and then we need the current date, so we'll say date. We'll get the year - 40 so this is going to be considered an instance method as opposed to a static method. So then what we would need to do is first of all kill Tinker so that we can restart it with our new method. And we would new app. App\Guitar, and then we would use that getVintageGuitars or what do we call it? getVintageGuitars, we could probably just called it getVintage but doing so will require us to restart Tinker. So getVintageGuitars and we can see that that is null. That's not really what I expected but that makes sense now because I didn't return anything. So while we're here, let's change this to just get, well let's just say vintage. Why not? And we will need to kill Tinker, so that we can start it back up. And then we will new up App\Guitar. And we will call vintage, this should give us a builder object. There we go, so now we can say get, and now we have all of the guitars that are at least older than 40 years. And so query scopes are a wonderful feature. It allows us to reuse query logic throughout our application.