TECH Insights

Viden og indsigter fra IT Minds' it-talenter

Soft deletes and pipelines

Skrevet af Mindster og Software Developer hos IT Minds on 27-03-20 08:19
Mindster og Software Developer hos IT Minds

Knitzilla is a knitting app that I created for my wife.
Originally it was only supposed to keep track of how many rows she knitted, but in time, it grew.

It is now at a stage where you can commit to several different knitting projects, and you can add and delete counters to each project.

Since I, in time, want my wife to be able to create a portfolio of all the knitting projects that she has finished I needed a system to put this in place.

Luckily for me, Laravel ships just such a feature out of the box.

To make my Project model able to support soft deletes I needed to mutate the user table in my database. This is easily done with a migration.

A quick:

Skærmbillede 2020-03-27 kl. 08.12.36

should fix that right up.

Now with my database updated, the only thing left is to tell my model that I want to use this feature.

Since all my database communication goes through the eloquent model, these things become a breeze.

Skærmbillede 2020-03-27 kl. 08.13.14

Very nice indeed.
However, I need a new way to get all projects now, even the deleted ones. Wouldn't be much of a portfolio if you could never retrieve the actual items.
This is where it becomes a wee bit advanced.

If you have ever written a backend, you surely know what request middleware is, and you properly like it.

What if I told you that such pipelines are not reserved for requests? Laravel provides their abstraction of pipelines, free to use, if you know how to.

I will just show this with a pipeline with a single middleware function, but these can be as large or small as you would like them to be.

First of all, the abstract class we will be working with.


Skærmbillede 2020-03-27 kl. 08.13.53

A few things to notice here:

  1. In the filter_name function, I am using a function called class_basename with this context. This is a standard PHP function that extracts the name of the class which it is called with. The cool thing is that it returns the inheritor's name. This means that this function can be implemented in our base class, and reused in all the different filters we want to provide.

    • This pattern is depending on a specific naming convention. It expects the filters is the snake case name of the query params from our request.
    • This means a class name of Deleted would need to have ?deleted=true in the query params, and BeforeDate would need ?before_date=<some date>
  2. With the last function in the class, we are telling everyone who extends this class that they have to implement an apply_filterfunction.

  3. In the handle function we decide if this specific piece if middleware needs to activate. If it don't, we just invoke the $next piece of middleware.
    If it does, however, we defer the next in the chain to the apply_filter function.

Skærmbillede 2020-03-27 kl. 08.15.00

With all the smart things already packed away in our AbstractQueryablewe only need to add the invoke the necessary function on the query builder.

Skærmbillede 2020-03-27 kl. 08.15.35

Now it all ties together, we can define a static method on our model and begin the pipeline.
The code here is pretty self-explanatory. We get the Pipeline from our app service container, and through it, we want to send a Project::query()which returns a chainable query much like Entity frameworks fluent query builder.

The thenReturn gives back the query builder and from there was some functionality I want to always be present.

I want all related models to the project, and I am only interested in the project connected to the id the function is invoked with.

Pipelines open up for some pretty neat functionality, and it gives a way to specify a single endpoint, and then have the user, through the pipeline define how the data should be i.e sorted, filtered, paginated and so on.

Maybe it would be nice to have a ?paginate=15&page=1 for the ones who want to paginate, and all, for the ones who want all (i wouldn't know why).


If you have read my other laravel posts, you know I like to test it.
So just for the eager learner, I have provided the code I used to test the deleted functionality of the pipeline I created.


Skærmbillede 2020-03-27 kl. 08.16.45


Insights fra de bedste softwaretalenter

En del af IT Minds’ DNA er, at vi spotter og tiltrækker de bedste softwaretalenter, som er stærke i de nyeste teknologier og frameworks. Derfor vil vi gerne dele ud af vores viden og erfaringer vores konsulenter opsamler, når de afprøver og arbejder med nye teknologier og frameworks.

Seneste indlæg