Sitemap

Say Goodbye to Hard-Coding: Manage Laravel Model Columns Efficiently

3 min readJan 28, 2025

--

Zoom image will be displayed
Photo by Mohammad Rahmani on Unsplash

It’s been a few years since I last used Laravel, and now I’m diving back into it. While exploring tutorials out there, have you noticed the endless repetitive typing of field names everywhere? Controllers, RequestForms, Models, Repositories — you name it. It’s like déjà vu for your fingers.

And when you’re working with a team of developers, this can lead to:

  • Column/Field name typing errors 😅
  • Lack of transparency — there’s no centralised place to maintain column/field names, and the lack of IntelliSense further complicates the process.
  • Maintenance nightmares — implementing changes becomes more of a challenge than it needs to be.

After dealing with this, I thought, Why not make life easier for me and my team? So, I created a simple script to generate model columns automatically.

The Script

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class MakeModelColumnsCommand extends Command
{
const COLUMN = 'Column';
const APP_SUPPORT_MODEL_COLUMNS = 'Support/ModelColumns';
const PERMISSION_0775 = 0775;
const STUB_MODEL_COLUMN = 'stubs/model.column.stub';

private $errTableDoesNotExists = "Table '%s' does not exist.";

protected $signature = 'make:model-columns {table}';
protected $description = 'Generate or update a class with constants for table column names';

public function handle()
{
$table = $this->argument('table');

$className = $this->getClassName($this->toSingularStudly($table));
$filePath = $this->getFilePath($className);

$columns = $this->getTableColumns($table);
if ($columns == null) {
return Command::FAILURE;
}

$stubPath = self::STUB_MODEL_COLUMN;
if ($this->isStubPathExists($stubPath)) {
$this->generateModelColumns($filePath, $className, $columns, $stubPath);
} else {
return Command::FAILURE;
}

return Command::SUCCESS;
}

private function getClassName($table): string
{
return $this->toSingularStudly($table) . self::COLUMN;
}

private function getFilePath(string $className): string
{
return app_path(self::APP_SUPPORT_MODEL_COLUMNS . "/{$className}.php");
}

private function isStubPathExists(string $stubPath) : bool {
if (!file_exists($stubPath)) {
$this->error("Stub file not found at: {$stubPath}");
return false;
}
return true;
}

private function generateModelColumns(string $filePath, string $className, array $columns, string $stubPath)
{
$stubContent = $this->generateStubContent($stubPath, $className, $columns);

$directory = dirname($filePath);
if (!is_dir($directory)) {
mkdir($directory, self::PERMISSION_0775, true);
}

file_put_contents($filePath, $stubContent);

$this->info("Class '{$className}' generated/updated successfully at '{$filePath}'.");
}

private function generateStubContent(string $stubPath, string $className, array $columns): string
{
$constants = array_map(function ($column) {
$constantName = strtoupper(Str::snake($column));
return " public const {$constantName} = '{$column}';";
}, $columns);

$constantsCode = implode("\n", $constants);

$stubContent = file_get_contents($stubPath);

return str_replace(
['{{ className }}', '{{ constants }}'],
[$className, $constantsCode],
$stubContent
);
}

private function getTableColumns(string $table): ?array {
if (!Schema::hasTable($table)) {
$this->error(sprintf($this->errTableDoesNotExists, $table));

return null;
}

return Schema::getColumnListing($table);
}

private function toSingularStudly(string $string): string
{
return Str::studly(Str::singular($string));
}
}

Setting It Up

  1. Create a command using:
php artisan make:command MakeModelColumnsCommand

2. Copy and paste the script above into your newly created command file.

3. Publish the stub and create a new stub named model.column.stub:

php artisan stub:publish

4. Copy the following code into model.column.stub:

<?php

namespace App\Support\ModelColumns;

class {{ className }}
{
{{ constants }}
}

5. Migrate any table to expose the columns/fields

6. Finally, run the script:

php artisan make:model-columns {tableName}

Sample Output

After running the script, a file will be generated in app\Support\ModelColumns.

Here’s an example of the file generated for a users table:

<?php

namespace App\Support\ModelColumns;

class UserColumn
{
public const ID = 'id';
public const NAME = 'name';
public const EMAIL = 'email';
public const EMAIL_VERIFIED_AT = 'email_verified_at';
public const PASSWORD = 'password';
public const REMEMBER_TOKEN = 'remember_token';
public const CREATED_AT = 'created_at';
public const UPDATED_AT = 'updated_at';
}

Usage

In Request

<?php

namespace App\Http\Requests\User;

use Illuminate\Foundation\Http\FormRequest;

use App\Support\ModelColumns\UserColumn;

class CreateUserRequest extends FormRequest
{
public function rules(): array
{
return [
UserColumn::NAME => 'required|string|max:200',
UserColumn::PHONE_NO => 'required|string|max:20',
UserColumn::EMAIL => 'required|string|email|max:255|unique:users,email',
];
}
}

In Resource

<?php

namespace App\Http\Resources\User;

use App\Support\ModelColumns\UserColumn;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class GetUserResponse extends JsonResource
{
public function toArray(Request $request): array
{
return [
UserColumn::USER_ID => $this->user_id,
UserColumn::PHONE_NO => $this->phone_no,
UserColumn::EMAIL => $this->email
];
}
}

In Model

<?php

namespace App\Models;

use App\Support\ModelColumns\UserColumn;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
protected $fillable = [
UserColumn::NAME,
UserColumn::PHONE_NO,
UserColumn::EMAIL,
UserColumn::PASSWORD,
];
}

So, that’s it! With this script, you can say goodbye to the repetitive typing of field names and hello to cleaner, more maintainable code. Whether you’re working solo or with a team, this approach saves time, reduces errors, and brings much-needed transparency to your projects.

Give it a try and let me know how it works for you! If you have any suggestions or improvements, I’d love to hear them. Let’s make Laravel development a little less tedious and a lot more fun! 🚀

--

--

Responses (6)