Playing
01. Scope basics and their drawbacks

Transcript

00:00
In this course, I'm going to walk you through implementing custom query builders into your Laravel apps. And custom query builders are a direct replacement for scopes, which you may have used in the past or you may be using at the moment. So if you are fairly new and even if you've not used scopes before, we're going to take this episode to build out a very simple scope on the user model and then just discuss a couple of the drawbacks of this.
00:28
So I've got a fresh Laravel project here with the default migrations run, so we've got a users table here. The first thing that we're going to do is just go ahead and run phpArtisanTinker and using the factory that comes pre-created for us, we're just going to go ahead and create out three users here just so we've got some data to play with. So if we come over here, we've got three users.
00:51
Now, what could we scope by here? Well, we've got this email verified at column. So what we could do is get rid of a couple of these and create a scope within our user model that only pulls back users who have verified their email. Now, if you are new to scopes, let's take a look at how we would do this prior to introducing a scope.
01:13
So we're going to go ahead and just start things off by saying user get just to grab all users. And we're going to go ahead and dump them out just here, making sure we pull the namespace in for user. If we come over to the browser and give this a refresh, sure enough, we have three users. Now, if we wanted to grab all users who have verified their account or only users who have verified their account,
01:35
of course, what we're going to do is add in a where clause. So to do this, we're just going to go ahead and say where not null because this is a nullable field. And we're going to go ahead and pass in that email verified at column. If we head over, obviously, we're going to see one here because we only have one user who has verified their email.
01:57
OK, so when you're doing stuff like this in Laravel, typically you'll think, I want to go ahead and extract this out to a scope just to make it a little bit more convenient and a little bit cleaner for me to define when I am writing out code like this. To do this, we hop over to the model that we want to work with and we go ahead and create our method in here.
02:18
And we prefix this with scope and then we give the name of the thing that we want to call. So in my case, if we just hop back over to the file here, I might want to say user has verified email or you could even make it more explicit where has verified email. It's entirely up to you. Then we want to grab back just them users.
02:41
Now with scopes like this, what we're going to have to do is introduce the query method on here, which actually returns to us a Laravel builder. And then we go ahead and when we call this, Laravel will work out that this is a scope based on our prefix and it will go ahead and apply the query that we apply in here.
02:59
So let's go ahead and fill this in just in case you're new. So has verified email and into this method when it is invoked by Laravel, when we call it like this, we actually get a builder instance in here. So we can go ahead and namespace that if we want to.
03:15
And you can call this builder or you can call it query. I think in the documentation we see it called query. So in here now what we can do is just say query where not null and go ahead and call it like that. We don't need to return anything in here.
03:28
That's not important because this will just add on to the current builder that gets passed through for every call we make. Now I've mentioned that because later when we do introduce our custom query builders, we will have to return something. So just bear that in mind while you're watching.
03:45
Okay, so now that we have this scope and we're calling it over here, if we head over and give this a refresh, sure enough here we get exactly the same result. What I was talking about earlier is if we get rid of query here and just try to say user has verified email, because this is not a static method, we're going to see an error here.
04:02
And the reason that that doesn't work is just simply because Laravel then can't work out the scope name that we've defined. So that is a scope in a nutshell if you've never come across one or if you needed a refresher. Now what we want to do is talk about probably the two main drawbacks of scopes. The first drawback is that these will pollute your model.
04:23
If you start to create lots and lots of scopes, obviously not scopes with the same name, but you kind of get the idea, you're going to end up with a huge amount of methods in here that perhaps do very, very specific things. Now, if you're working on your own on a project, that might not matter as much. And then, of course, feel free to use these and just add as many as you need.
04:44
It's going to be much easier for you to track if you're working on your own. However, when you start to work as part of a team or you're working in open source, what you'll find is scopes will get introduced that do lots of different things. You may have some sort of crossover. Things get really messy.
05:01
You have lots of individual methods in here, which make it really hard to see what scopes are doing what. This isn't much of a big deal. I'm a huge advocate for using scopes and I really, really like them. But that can be a drawback, particularly if you're working on much larger projects. Now, the second drawback to this, which is probably more of an annoyance,
05:23
is that by default, this won't often autocomplete for you within your IDE. Now, by that, I mean if we were just using Laravel's query builder, for example, and we wanted to add a where clause, I can start typing where and you can see here that we get this definition for this method in here. I can go ahead and click on that. It will tell me what arguments I need to pass down,
05:47
which is the column, the operator, the value, and so on and so forth. But when we're working with scopes, because these are magically called based on their prefix, these will either not be filled for you or they'll be badly autofilled. So this one, we call it like has verified email.
06:04
So let's go ahead and start typing has verified email. And you can see that my editor has gone ahead and suggested this for me, but it suggested this as scope has verified email. So what I'm going to have to now do is go back, get rid of this scope part, lowercase the H,
06:24
call it as a method as it's intended, and then go ahead and start chaining on. So I don't at first glance when I use a query builder here have access within my editor by default, unless I have some sort of extension all of the scopes in here. Now that's not to say that like I said, you can't get an extension to do this for you.
06:43
You absolutely can. But if you think about other people again, if you're working as part of a larger team or you're working in open source, you might find that people will not have these extensions and therefore it might be better to use a custom query builder just to make this a little bit more explicit.
07:00
So there we go. We've got a working scope, which like I said are great, but we can improve on this particularly as our projects start to grow. So let's hop over to the next episode and start to build out a custom query builder, which I think you're going to find looks really nice.
4 episodes 23 mins

Overview

Using Eloquent query scopes in your project? Consider swapping them out for custom query builders. Custom query builders are model-specific, class-based builders that provide better organisation, IDE autocompletion, and more.

We'll start this course by defining some standard scopes, refactor them, and discuss the benefits of custom builders.

This course is for you if:

  • You're using query scopes, but they're bloating your models
  • You're working in a team and need more organisation in your project
  • You haven't used query scopes and want a primer, plus an alternative
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!