Adding URLs to our models can be very useful. Just imagine, we could automatically generate the URL with the help of Laravel in the background, then make it usable event from the model directly or maybe as a JSON representation from the front-end. We just use the property, and nothing else to do.
The Basic Concept
On the Laravel’s side, we have an easy job because we can use the framework’s route() helper. It means, we can pass any named route to the helper and the model instance, and as a result, we get the formatted URL we need.
Now, often we need to pass the JSON representation of a model instance to any JS service, where we don’t really have any route generator helper. So what we can do, is to generate the route in advance and pass it to the JSON as well.
The “Routable” Trait
Since most of the routes apply the RESTful concept in a Laravel app, most of the cases we can use route generation for almost every model. So it’s a good idea to make a trait and import it for those models where we want to use it. Let’s see the trait first:
trait Routable { /** * Get the api route. * * @return string */ public function getApiRouteAttribute() { return $this->id ? url('api', $this->baseRoute()) : null; } /** * Get the web route. * * @return string */ public function getWebRouteAttribute() { return $this->id ? url($this->baseRoute()) : null; } /** * Get the base route. * * @return string */ protected function baseRoute() { return sprintf('%s/%s', strtolower(str_plural(class_basename(static::class))), $this->id ); } }
So, what is going on here? First of all, we generate the base route, depending on the class basename. Then we append the model’s ID to the route. Then we get the web route and the API route. The only difference is that we append the api prefix for the API routes.
So, we have the accessors for both the web and the API routes. It means we can call ->web_route and ->api_route properties directly from our models. Now let’s move on, and see how to append them in the model’s JSON representation.
Appending Properties to the Model
Laravel offers an easy way to handle these. Just create a $appends property on your model and fill the properties you want to append. For us, it will look like this:
class Post extends Model { use Routable; /** * The accessors to append to the model's array form. * * @var array */ protected $appends = [ 'api_route', 'web_route', ]; // ... }
From this point, the URLs will be accessible from the model’s array and JSON form as well. It means from any JS service we can use it easily.
It’s automatically being generated behind the scenes, so we just need to append the properties and pull in the trait. Little, yet nice extension – at least for many cases.