This episode is for members only

Sign up to access "Easy Query Filters with Laravel Pipelines" right now.

Get started
Already a member? Sign in to continue
Playing
05. Passing additional arguments

Transcript

00:00
We've seen from each of the query filters that we've created we're using the request helper in Laravel. Now that's a common thing that we're going to have to use in each of these classes.
00:10
So the question is can we pass the request from here down into this pipeline instead of accessing this on its own inside of each one? Well the answer is kind of no but kind of yes. Now if we go and open the actual pipeline
00:28
class itself, so in the source code, let's go over to the send method here. Now you can see that this takes one argument, passable. This isn't split out so we can pass multiple items. We can literally just pass one thing which is what we're doing just here.
00:42
So unfortunately what we can't do is something like the following. We can't pass the request into the send method and then pick this up inside of each of our query filters like this for example. That's just not going to work. So there are a couple of ways around
00:57
this. One is probably a little bit overkill. The second is something that's a little bit more manageable. Okay so the first way that we could do this is create an object that holds not only the builder but also the query.
01:12
So let's just do this really roughly and let's just call this discussion filter object just for lack of a better name. So what we're going to do is effectively create an object which transfers both of these pieces of data through to this pipeline. So let's go
01:28
ahead and give this a namespace of just app and we will call this discussion filter object. So in here what we can basically do is just create out either some public properties, protected properties with getters or setters and just pass both of
01:44
these pieces of information in. So the first thing that we want is a builder. So let's go ahead and say public builder and this is just going to be called builder and we can also create out a public request
01:56
which is going to just be a request. So in this case let's just make sure we pull the namespaces in for each of these things. So from the relevant places we could go ahead and create a constructor in here to set these or we could actually just set these
02:10
directly within the constructor if you're using a high enough php version. So let's go ahead and do that just to make things a little bit clearer and now what we can do is just pass these two things into here pass the entire object through to this and then we'll have access to both of
02:25
the things. So let's look at how we would do this. Let's go ahead and create a new discussion filter object and we're going to pass the query builder in first and then the request itself
02:39
in second. So now we've got an entire object in here which we can then pass through with both of them pieces of data set as public properties. So how will this change our filters? Let's just get rid of the created at order query filter just so we can test
02:54
it on this unsolved query filter. Let's go ahead and open that up and in here we're not going to get a builder now we're now going to get a discussion filter object and we could just call this filter object for example and then here what we can do is just
03:08
change things around. So filter object builder and in here filter object builder and of course we now have access to our query so or our request so we can just say filter object request and there we go. So now we've got them two things tucked away in this one
03:28
object and it makes it a little bit more convenient. Let's go ahead and say unsolved true and there we go it works in exactly the same way. Now to me this is slightly overkill just depending on how big your app
03:39
gets so i'm going to go ahead and just get rid of all of this. It's a good option if things do get really complicated but really all we need to do in our case is pass through a specific value to each of these filters. So we'll return
03:54
this back to how it was if we just give this a refresh it still works. Let's look at how we can do this in a much more simple way without having to create out this discussion filter object. Okay so let's first of all take a look at how middleware works and we know that
04:09
pipelines use middleware. So let's open middleware and let's open redirect if authenticated. Now you can see here that when we call the handle method which is a class here that's piped through a pipeline we get the request which is the thing
04:22
that we're potentially checking modifying we get next which we always call in here much like we're doing within our pipelines but then we get this additional argument in here which is guards. Now the way that we use this particular middleware if we just head over to
04:35
routes and web let's just say we're applying this middleware to here what we would do is we would say redirect if authenticated. So let's go ahead and apply that middleware in here and then we would go ahead and append
04:50
onto this the thing that we need with a colon. So in this case the guards are some guards that we want to use and we would just pass them in. Now that's a really simple example and of course the implementation is probably different but that's pretty
05:06
much what we do. So as an example let's go ahead and append onto this fully qualified namespace using a colon abc just to test things out. So again we'll get rid of this filter here we'll open up our unsolved query
05:19
filter and let's go ahead and grab that value out in here and i'm just going to die dump on that value. So if we just come over and give that a refresh there we go. So what we've done with this is we've gone ahead and passed a colon
05:32
anything after this is going to be passed as the arguments to this class or the handle method within this class. Let's check what happens when we comma separate this with def and we give this a refresh you can see that we don't get anything within that
05:47
value but if we were to say second value and go ahead and dump on this as well you can see we get def. So we can pass as many arguments as we want here with these being comma separated. So with that said what we can now do
06:04
is instead of accessing the request directly we can pass the value from here directly through to this class. Now this makes it a little bit more messy in the implementation here but it makes it a lot easier to test which is what we're going to be looking
06:19
at in the next episode. So what do we want to pass through to here? Well we want to pass whether the query has unsolved or not. This could be any data. So we're going to say request get unsolved. That's pretty much all we
06:33
need to do. So now this value is going to be a boolean so we could type in this to a boolean although it's actually probably going to come back as a string and we can now replace this out with value and there we go. So we're not now using
06:46
and relying on that global query helper inside of here which is going to make testing this individual class a lot easier. Let's head over and just give this a refresh and you can see this still works if we get rid of this
06:59
we get exactly the same thing. Now it's entirely up to you if you want to use request in here it doesn't really matter too much. It makes it a little bit harder to test but if you don't like this way of doing things then of course
07:11
feel free to use the other method. I'm going to leave this one without this just so we have a reference to both. Okay now that we've changed stuff up a little bit let's head over to the next episode and write a test for our unsolved query filter to see how we can actually write tests for these.
6 episodes 35 mins

Overview

Applying result filtering with query strings can mess up your controllers quickly. Let's reach for a solution using Pipelines, an undocumented but seriously powerful feature of Laravel.

Every filter (e.g. only show activate users) will have its own class, neatly tucked away. We'll also cover testing, and see how this method makes isolated testing much easier.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!