Refactoring logic into a policy method

So much nicer

Joel Clermont
Joel Clermont

I was working on an application that had a private administrative app paired with a public-facing website.

To make things easier for admins, we would include links to the public version of some content right next to the place you edit the content in the admin app.

But there were a few rules around when we wanted to generate one of those public-facing links. There was a hierarchy of events, locations, and regions, and depending on the configuration or status of each level of the hierarchy, it might not be appropriate to generate a public link.

The logic was pretty straightforward, but there were 2 - 4 checks, and they were in maybe 6 or 7 different Blade files. I had implemented it with simple if or unless directives, but during PR review, Aaron suggested refactoring it to a policy method.

In reality, it would end up being a policy method on 3 different models, but we named them all canShowPublicLink, so the Blade logic refactored to be simpler, more readable, and now all the logic was in a common spot.

But there was an additional benefit to this refactor: it made testing a lot easier. I can test a policy by just creating a model and calling the policy method with that model. I no longer had to set up a more complex feature test and simulate a request into the application to exercise the policy logic.

I'd still add an assertion to one of my feature tests to make sure the policy is actually wired up, but I can fully test the policy logic much more easily now.

I was a little annoyed at Aaron's suggestion at first, but I ended up really liking the refactor. Policies are useful for more than just controlling user actions. They can also be a reasonable place to put reusable logic like this as well.

Here to help,


P.S. Every tip that I share also goes through a PR review. As did all the content in our Laravel-focused books.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.