use BaseTrait;

There is much copy pasted boilerplate when working with Laravel’s Eloquent ORM. For example, it would be common to include these Accessors across Models to format default timestamps:

<?php
...
	public function getCreatedAtAttribute($attr) {
		return Carbon::parse($attr)->toIso8601String();
	}

	public function getUpdatedAtAttribute($attr) {
		return Carbon::parse($attr)->toIso8601String();
	}

But anyone who works enough with code knows that copy pasting sucks, especially when the logic will always be common across the instances where it is duplicated. So we create a BaseModel that stores these common definitions. All classes will extend from this instead of Eloquent’s default Model.

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class BaseModel extends Model {
	/******************
	 * Common properties, accessors and mutators here */
}

And in the other models:

<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class UserModel extends BaseModel {
	/******************
	 * Ahh, such functionality, much clean! */
}

But wait a second, what if there is a need for a specified class to extend from some other class? For example, the UserModel must extend from Authenticatable to take advantage of Laravel’s built in authentication library. We need to extend from BaseModel to tap into common functionality, and yet another class for another set of functionality. But a class cannot simultaneously extend from more than one class! Enter the trait:

<?php
namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;

trait BaseTrait {
	use SoftDeletes;
	/******************
	 * Common properties, accessors and mutators here */
}
<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class UserModel extends Authenticatable {
	use BaseTrait;
	/******************
	 * Ahh, such functionality, much clean!
	 * Definitions from BaseTrait and Authenticable both exist here */
}

The definitions from BaseTrait are essentially injected into the consumer class. A BaseTrait can even be taken another step further by defining custom magic properties. For example, if we want to cast a set of custom attributes in any consumer class to a string:

<?php
namespace App\Models;

trait BaseTrait {
	public function toArray() {
		$array = parent::toArray();
		if (isset($this->strings)) {
			foreach ($this->strings as $stringProperty) {
				$array[$stringProperty] = (string) $this->{$stringProperty};
			}
		}
		return $array;
	}
}

And using it would be a simple matter of:

<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class UserModel extends Authenticatable {
	use BaseModel;
	$strings = ['name', 'gender'];
	// other usual things
}

Instead of casting name and gender to strings by defining individual accessors, they are automatically handled because the trait watches out for a $strings definition in the consumer classes. BaseTrait has significantly reduced the amount of boilerplate code across all my Laravel projects, and I hope this will help you too. Reach out for quick clarifications about adopting this, or if you think there can be a better approach.

sudo rm -rf /

“The best time to plant a tree was 20 years ago. The second best time is today.”