Custom Blueprint In Laravel Model

Harsh Shah
Nov 20 · 4 min read

Object-Oriented Programming or better known as OOPs is one of the major pillars of any programming language. One of the biggest benefits of the OOPs is Inheritance and here we can use that concept to implement Custom Blueprint.

Before we understand the Custom Blueprint, let us discuss what is a Blueprint class?

Blueprint Class

In the real world, we have to do migrations numerous times. When we make any migration, a file will be created in migrations folder automatically, which will have two methods by default called “up” and “down”. It consists of logic as per the requirement of a particular migration.

To define a new table and add columns to the table, we can use the Blueprint instance. Following are the simple lines of code as how Blueprint object utilized in migration.

public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}

Problem Statement

Let’s take an example of the Employee Management System. Each employee like System Admin, HR Manager or Project Manager will have different permissions based on different modules in the system. Reference the below figures.

Generally, a team member from HR department handles the leaves of an employee or PM handles the billing part of the project. Now, to keep track of edits or changes, we have to have fields like created_at, created_by, updated_at, updated_by, deleted_at, and deleted_by in every model.

  1. Timestamps() method provides created_at and updated_at fields where SoftDeletes() method provides delete_at field. Now our requirements can be achieved by adding other fields like created_by, updated_by and deleted_by in every model manually.
  2. In any unfortunate circumstances, the need of changing the name of any field, it is going to be a tedious task to do it in every model.

Solution

To solve both problems, we should move all those common fields in one place and this is done by creating a new class CustomBlueprint.

Because of extending default Blueprint class, we can use all default fields and methods which are given by it like string, char, decimal, timestamps(), etc. Now, our first step is to create a method like commonFields() and declared all common fields in it that are necessary for every model. After this, it is time to modify the migration file.

public function up()
{
$schema = DB::connection()->getSchemaBuilder();
}

We need a schema builder instance for the connection and it is done by using getSchemaBuilder() method in up function of migration.

$schema->blueprintResolver(function ($table, $callback) {
return new CustomBlueprint($table, $callback);
});

The blueprintResolver is used to set the blueprint resolver for the schema. By returning our new CustomBlueprint object, we can change the default behavior of the blueprint object.

$schema->create('roles', function (CustomBlueprint $table) {
$table->bigIncrements('id');
$table->string('name')->unique();
$table->commonFields();
});

Now, we can use the object of CustomBlueprint class to add columns instead of default Blueprint class. Because of commonFields() method, the model “role” will get created_at, updated_by and all other fields that are defined in it. After migrating this migration, we can see the following structure of the model “role ”.

Now final migration file is like

If we follow the same procedure for every model, those fields are automatically added to it.

Best Solution

Laravel Macros are a great way of extending Laravel’s core classes and add extra functionality required for our application. It is a way to add some missing functionality to Laravel’s internal component with a piece of code that doesn’t exist in the Laravel class. Blueprint is macroable, so we can just define a macro on it in a service provider and get the same functionality that we required.

public function boot()
{
Blueprint::macro('commonFields', function () {
$this->timestamp('created_at')->nullable();
$this->unsignedBigInteger('created_by')->nullable();
...
});
}

Footnotes

If you’ve found some better ideas to implement this or have any doubts, leave a comment below and I’ll try to reply ASAP.

The Startup

Medium's largest active publication, followed by +538K people. Follow to join our community.

Thanks to Jamil Noyda and Shashwat Bhatt

Harsh Shah

Written by

The Startup

Medium's largest active publication, followed by +538K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade