How To Build An Admin In Laravel Using TDD

by Nick Basileon Jan 24, 2018

Whether you're building a simple blog or a full-on enterprise application, at some point you're going to need an admin section to manage your project. One of the hardest parts of building an admin section is getting a feel for how robust it should be.

Do we need a separate model for admin users, or can they be extensions of our regular users? Should we manage their admin status in data, or can we manage it in the code to start? Will we ever need to add more admins, or can we start with just us?

These are fantastic questions to be asking, and they really highlight the range of options available to us. For this post, let's focus on building a quick admin section that only admins can see by extending our User model to support admins.

Set-Up

For this project, we're going to be using a default Laravel installation. To get that up and running, check out my previous blog post on setting up a Laravel 5.5 project.

We'll also be using my Laravel starter auth bootstrap, so we don't have to worry about configuring our initial project. You can find it here on GitHub.

Updating Our Users

Let's get the ball rolling by extending our User model to support our new admins. Since we're using TDD to build our admin, let's stub out some tests for us to follow.

We can run php artisan make:test UserTest --unit from our terminal to generate our unit test. We're going to start with a unit test because we're not testing any features of our app. Instead, we're testing the lower-level functionality that our users can be admins.

Our first two tests will be pretty simple. We just want to make sure that users can and can't be admins. So, our tests will look like this:

While this works great, I'm a little nervous about hard-coding the type values into our factory. What happens if we need to change them in the future, or how will we even remember them? Well, we can take advantage of our User model and PHP class constants to manage our types in one place.

Now, we're maintaining our type definitions in our User model and we can reference them throughout our project as needed. This will really help us keep our code more consistent and maintainable. With our factory and migration ready, it's time to update our model.

That'll do it! Now that our Users can be admins, let's scaffold an admin dashboard that only they can look at.

Admin Views

Once again, we'll start with a test! Since we'll be testing a feature of our application, we're going to want to use a feature test this time. To create that, we'll run php artisan make:test AdminTest. Now we can add our tests.

These are pretty similar to our last tests. We're checking that regular users don't have access to our /admin route and that admins do have access.

One extra wrinkle that you can see is that we're making use of the actingAs()helper method. This lets us log in and authenticate our created user for the test. Now, let's make get these tests to green.

First, we'll add the /admin route in web.php.

Route::get('/admin', 'HomeController@admin')->name('admin');

For this tutorial, we'll keep using the HomeController. But, you might want to consider using a dedicated AdminController for your project. Inside of HomeController.php, we can add our admin() method like so:

As you can see, if the currently authenticated user is an admin, then we let her through. Otherwise, we send her back to the /home route. With our middleware ready to go, we can now register it in our Kernel.php so we can use it.

Inside of Kernel.php, there's a protected array called $routeMiddleware. We can register our custom middleware in here.

Now we're applying our middleware to protect this route. Let's run our tests to make sure everything is working.

Bada bing bada boom, we've got ourselves a working middleware. Now, let's add a link to the nav that our admins can use to access the admin section. Inside of our nav.blade.php partial, we can see the following:

Now, we can see that admin users have access to this link and regular users don't!

Regular User

Admin User

And there you have it! A simple admin section that's isolated from our regular users.

The Wrap-Up

At some point or another, most projects will need an admin section. This approach shows you how quick and easy it can be to set one up. But, it's certainly not the only way to do it.

You can take this all a step further by creating a separate model for admins; using policies for authorization, or by leveraging a full-on roles package like the excellent Spatie larave-permission. Whether or not you choose to go down those paths is up to you! As always, feel free to ask me any questions on Twitter. And until next time, happy coding!

Nick Basile

I'm a full-stack developer working with Vue.js, Laravel, and more. In my spare time, I read, tweet, blog, and put together a newsletter.