Laravel Nova: So far, so good!

Megan Lyle
Neighborhoods.com Engineering
7 min readSep 17, 2018

About a year or so ago, I was wandering through my old internet haunts (as you occasionally do, provided you can remember those ancient passwords) when I stumbled across one that I was surprised to find even still open. It was obviously someone’s college pet project, a mess of old-school php programming and hardcoded logic that probably should have crashed and burned years ago, but still seemed to be limping along.

It had been years on top of years, but when I reached out to the current administration, they were gung-ho about letting me take a look at revisiting the codebase for them. It was win-win — they got the (hopefully vastly improved) update and I got the valuable experience of working on a nightmare renovation in a zero-stress, zero-expectation environment.

My number one takeaway a year after taking on this task? Amin panels are the absolute worst variety of coding. The site, as it stood before I began, required any new data to be entered manually through whatever database driver you chose (phpmyadmin usually). It was my job to create form after form allowing staff to enter data in a format that they could understand, upload files in a saner manner than “rename this file this exact name and ftp it up to the server”, and validate cross-data relationships. Especially when you got down to some of the complex, nested relationships that can exist on a site like this one, the coding was repetitive, arduous, and not at all fun. Who wants to write form after form of data entry interfaces?

Enter Laravel Nova.

After watching the keynote that Taylor Otwell gave at this year’s Laracon, I don’t think I’ve ever handed over one hundred dollars quicker. And this framework… just to give some perspective: I have spent at least the last 6 months (in my spare time, granted) building a comprehensive administrative backend for this new website. But by using Laravel Nova, I was able to not only recreate 6 months of work, but surpass it, all in one weekend of development.

6 months worth of work blown away in a single weekend, and I can’t even be mad about it.

Sounds neat, but how does it work?

The video above does a very good job of walking through, but since it is a long watch, I will try to condense. Essentially, Nova hooks into your already present Laravel models and allows you to, with minimal code, create form fields that allow you to modify those data models.

An example of a Nova Resource file — the fields() method returns an array definition of all of a model’s editable data fields/formats.
The corresponding form display.

Not only does it allow you to represent any manner of straight data fields (strings, numbers, files, even code blobs), but it also allows you to work with Laravel’s Eloquent relationships. One to many relations become selects; Many to many relations become tables. All with only one or two lines of code.

Two HasMany relationships are defined on an Event Resource — child Sets and child Forums.
With only the above lines, referencing relationships defined on the Event Model, we now have two tables for adding/removing/modifying children on our Event Resource.

The positives here speak for themselves. Suddenly it is almost negligible to provide a way to manage data behind the scenes in a Laravel application. The tying in of Policies to the authentication only takes it another step closer to being zero effort since Policies are used throughout Laravel’s request structure as well. As a developer, I can now worry less about creating an endless array of forms and more about creating the cool features that will actually use the data provided.

My favorite part so far has been that, even with all of this provided functionality, it is still pretty easy to make custom modifications to better suit an application’s needs. For example: Nova’s current file/image field assumes that you wish to store the file’s name in a column within the database. This is not how my application is set up, however. I am using S3 to store images, and because each model relationship has a single image associated, I take the easy path of simply naming my files with my model ID. I assume that, since I will never be accessing the files without a UI, having readable names definitely isn’t a priority for me.

No problem! By simply looking at the Nova Image class (all the files are there, in the directory that you install when you add Nova to your Laravel project), I was able to find exactly what methods I needed to override in order to skip the database step altogether.

By overriding the Avatar field’s constructor, I was able to set up custom definitions of the thumbnail retrieval, image preview, store, etc for consistent storing and retrieving of S3 images by model value.
Now I am able to call S3Avatar just like I would the regular Avatar field and provide it the values it needs to store my image by id.

Throw them in a custom class and voila! Back to only taking 5 minutes to add a new image field to a resource form.

When you combine this core file access with the ability to add actions, custom fields, and even entire tools, Nova is just as flexible as you have the time and energy to make it!

A user action calling one of my existing Service method. This can preform all of the necessary logic to grant a user (or multiple users!) an item in their inventory.
When I include the action in the User Resource, I am able to call it on whatever user(s) I choose from the list by choosing it from the options in the upper right corner.

(Being able to still use my previously-written Service methods to add custom actions has been a huge win for me with this toolset.)

While cool, Nova is still a work in progress

Rome wasn’t built in a day, and despite being a refined and near-invaluable toolset, Nova does have its issues. There is a GitHub repo full of them, if you are interested (I know that I am. There is something extremely neat about watching a project evolve and feeling like a part of its growth).

Some of the issues I’ve stumbled upon (and a few that are preferences, from my initial opinions):

Policy permissions do not apply well to relationships. In order to attach one resource to another (IE, to grant a user a new role), the user attaching it must also have creation permissions on the Role resource. That means, for example, in order to grant the permission for someone to promote moderators, I would also need to give them the permission to create entirely new roles in the system.

Navigation is a little clunky. There is an update planned to allow resource grouping, which will help a lot with this. The current method of simply listing items in the sidebar can make things a little hard to find, especially if you have a ton of resources. I did discover, however, that you can optionally hide resources from the side navigation. This is nice for those supplemental resources that don’t really need to be managed outside of their nested parents.

Relationship labels aren’t customizable. This can make data specifications hard on a resource. For example — one of my models has an array of users, but they aren’t only users. They are “Artists”, or the person/people responsible for creating the associated artwork. Yet unless I want every instance of a user relationship to have the title of “Artists”, I am unable to set this as the label. So my Artists instead become Users, nonspecific and potentially confusing for anyone coming in to edit data down the line.

No option to login by username vs. email. Anyone who has worked with Laravel’s auth may know that, by default, it uses email and password. It is possible to easily update this to be username/password instead, though, by modifying the User model. Nova has its own login screen that appears when a session times out, but this does not take the auth override into account, nor seem to offer a simple solution of its own (yet).

Load times can be slow. I’m unsure as of now if this is my own implementation or Nova in general, but when I view an index for a table that has thousands of records, it seems to load rather slowly despite returning a subset of paginated results.

The UI is decidedly unresponsive. It may be an odd desire to be able to manage data from a phone, but with how on-the-go things tend to be nowadays, it would be nice! I am constantly mobile and would love to be able to make quick updates from an adjusted, perhaps limited mobile panel.

Nova will evolve, I’m sure, as it continually gains traction and users. Already multiple versions have popped up fixing issues reported these first few weeks, and the chatter is beginning to grow as developers try it out on their own applications. I would not be surprised if some of the above see fixes coming extremely soon (if they have not landed already since I wrote this).

All said and done, it is still a rather elegant and full-fledged solution to a very common problem, and baked into Laravel’s implementation like it is, requires minimal hassle to use and maintain. In the past few weeks I’ve gone from dreading working on the admin panel to enjoying it, and that alone has made Nova well worth trying out so far!

--

--