How I am using Laravel models for re-usability
Laravel models are very useful when it comes to re-usability of the code. You can define a function once and call it in any controller or trait you want. Although the default model structure in Laravel comes with Eloquent, which is a way to interact with database directly. Today, I will share you how I am using Laravel models with query builders.
Let’s say I have a “User” model and I want to create 2 functions: 1 to fetch multiple records and 1 to fetch single record. You need to know that Eloquent returns all the fields of the table but in this tutorial, we will create a custom function to return specific fields only. So following will be the code that goes in your User model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
// include database class
use DB;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
// map the collection to an array
private static function map($collection)
{
// array to return
$arr = [];
// loop through the collection
foreach ($collection as $c)
{
// create an object to return specific fields
$obj = [
"id" => $c->id ?? 0,
"name" => $c->name ?? ""
];
// insert the object in an array
array_push($arr, (object) $obj);
}
// return the array
return $arr;
}
// to fetch multiple records
public static function fetch($search)
{
// fetch users where name matches
$users = DB::table("users")
->where("name", "LIKE", "%" . $search . "%")
->paginate();
// don't want to return all the fields in users table
// so create a custom mapping function
return self::map($users);
}
// to fetch single record
public static function fetch_single($id)
{
// fetch user where ID matches
$user = DB::table("users")
->where("id", "=", $id)
->first();
// return null if no record found
if (!$user)
{
return null;
}
// this map will return an array of 1 element only, so we are returning only first index
return self::map(collect([$user]))[0];
}
}
Comments has been added with each line for explanation. Important lines are being highlighted. You have 2 public functions that you can call from your controllers, and 1 private function that can only be called by this model. In our map($collection) function, we are returning only the fields we want. This helps when you are developing an API, so you only have to return the data needed, not all columns. Note that we are using static functions so we can call the functions directly without creating an object. That is one of the benefits of PHP because there is no fear of memory leak because each request is treated as a separate process. If you are inside a static function, then only the static functions of that class can be called. That is why our map function is static too.
Now that’s how you can call these methods from your controller:
<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::fetch("adnan");
$user = User::fetch_single(1);
dd([$users, $user]);
}
}
You can see that it is super-easy and super-useful. You can use it in as many places as you want. I have used this technique in one of my project called Job Entry. It is a job board platform developed in React JS and Laravel. It helps recruiters find talent and job seekers find jobs.