loading...

Overriding Laravel’s Default Models Folder using Artisan Command

drumzminister profile image Elisha Ukpong Originally published at Medium on ・3 min read

A few weeks ago, the creator of Laravel, Taylor Otwell made a poll asking the framework’s users how they arrange their model files in the app folder.

The framework default stores all models in the app folder directly but most developers and me inclusive would prefer to have a specific models folder to house all models.

Default Laravel Models arrangement.

My way of arranging models.

Following this method of arranging models comes with a bit of tediousness as the folder name has to be specified as a namespace when creating the model using the artisan command. To create a model the default way, you can run this command below in the terminal:

php artisan make:model Bank

This command will create a new Bank model class and put the file directly in the app folder.

To create a model directly into any other folder, for me, the Models folder, this has to be specified when running the command, see below:

php artisan make:model Models\Bank

While doing this might not look like a big deal any time you want to create a new model, but having more than one developer on the project or creating a lot of models over time, you might tend to forget adding the _Models\_ prefix every time and that will create the model into the default app folder, not what we want.

To fix this, we can extend the Laravel’s default model creation artisan command and edit the default namespace/folder so we do not have to prepend the namespace/folder name while creating a new model.

Note: The folder name, is the namespace name too.

Firstly, create a new artisan command:

php artisan make:command ModelMakeCommand

This creates a new command class/file in the app\Console\Commands folder with contents:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ModelMakeCommand extends Command
{
_/\*\*  
     \* The name and signature of the console command.  
     \*  
     \*_ **_@var_** _string  
     \*/_ protected $signature = 'command:name';

_/\*\*  
     \* The console command description.  
     \*  
     \*_ **_@var_** _string  
     \*/_ protected $description = 'Command description';

_/\*\*  
     \* Create a new command instance.  
     \*  
     \*_ **_@return_** _void  
     \*/_ public function \_\_construct()
    {
        parent::_\_\_construct_();
    }

_/\*\*  
     \* Execute the console command.  
     \*  
     \*_ **_@return_** _int  
     \*/_ public function handle()
    {
        return 0;
    }
}

Secondly, we will change the class that our ModelMakeClass extends from Illuminate\Console\Command to Illuminate\Foundation\Console\ModelMakeCommand

Thirdly, we will empty the ModelMakeClass of its default methods and create a new method called getDefaultNamespace in the class to handle the task we want it to do (this method overrides the one in the Illuminate\Foundation\Console\ModelMakeCommand we are extending).

The ModelMakeClass becomes:

<?php

namespace App\Console\Commands;

use Illuminate\Foundation\Console\ModelMakeCommand as Command;

class ModelMakeCommand extends _Command_  
{

_/\*\*  
     \* Get the default namespace for the class.  
     \*  
     \*_ **_@param_** _string $rootNamespace  
     \*_ **_@return_** _string  
     \*/_ protected function getDefaultNamespace($rootNamespace)
    {
        //logic to change default behaviour
    }

}

The final thing to add to the new command class we just created is the logic to make our folder the default folder to put model files, in my case the Models folder.

The two different versions of the getDefaultNamespace methods.

Our new command class now becomes:

<?php

namespace App\Console\Commands;

use Illuminate\Foundation\Console\ModelMakeCommand as Command;

class ModelMakeCommand extends _Command_  
{
_/\*\*  
     \* Get the default namespace for the class.  
     \*  
     \*_ **_@param_** _string $rootNamespace  
     \*_ **_@return_** _string  
     \*/_ protected function getDefaultNamespace($rootNamespace)
    {
        return "{$rootNamespace}\Models";
    }
}

Finally, running the artisan command to create a new model will put the models in the app\Models folder by default 🙂.

TL;DR:

To change the default model folder in a Laravel app

  • Create a new artisan command with name ModelMakeCommand
  • Extend the Illuminate\Foundation\Console\ModelMakeCommand class instead of the Illuminate\Console\Command class.
  • Remove other methods and attributes from the class and then create a new method called getDefaultNamespace with content:
_/\*\*  
     \* Get the default namespace for the class.  
     \*  
     \*_ **_@param_** _string $rootNamespace  
     \*_ **_@return_** _string  
     \*/_ protected function getDefaultNamespace($rootNamespace)
    {
        return "{$rootNamespace}\Models";
    }
  • The full class becomes:
<?php

namespace App\Console\Commands;

use Illuminate\Foundation\Console\ModelMakeCommand as Command;

class ModelMakeCommand extends _Command_  
{
_/\*\*  
     \* Get the default namespace for the class.  
     \*  
     \*_ **_@param_** _string $rootNamespace  
     \*_ **_@return_** _string  
     \*/_ protected function getDefaultNamespace($rootNamespace)
    {
        return "{$rootNamespace}\Models";
    }
}
  • Run model creation artisan command and the models will be seen in the app\Models folder.

Thanks

Discussion

pic
Editor guide