In this Blog, we'll understand mutators and accessors of the Eloquent ORM in the Laravel framework by examples.
In Laravel, Accessors, and Mutators allows us to alter data while saving and fetching. As per the name Accessor alters data while accessing and Mutators modify data while saving. The major difference between accessor and Mutator is that data modification in accessor is temporary while in mutator modify data is stored into the database.
For example, if we want to store a user name in upper case into our database then we can define a mutator for that so when we save the model it will automatically convert the name into uppercase and also store name in uppercase.
Suppose we store the user's name as first name and last name. We want to display full user names across various pages then we need to add it manually Right!!! But using accessors we can create an attribute that merges it and use that attribute whenever required.
Let's take a practical example. Here, we will create Post Model and define Accessor and Mutator on it.
To create model , enter below command into your terminal :
php artisan make:model Post -m
It will create Post.php at App\Models Directory and migration file into database\migratations directory. Let's modify it one by one "
app\Models\Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'content',
'user',
];
}
database/migrations/timestamp_posts_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->string('user');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
Here, we have created basic database structure for our posts table now it's time to migrate it. Enter below command to migrate :
php artisan migrate
Titles generally use title case. which means, the first character of each word in a string to uppercase. Here, we will take user input into free text and store it into lower case using Mutator and use title into title case while displaying using accessors.
Let's define a Mutator and accessor for the title attribute. The Mutator will be automatically called when we attempt to set the value of the title attribute on the model and Accessor will convert title into title case while fetching data.
Syntax :
//Accessor
public function get{AtributeName}Attribute($value)
{
return converted value;
}
//Mutator
public function set{AttributeName}Attribute($value)
{
$this->attributes['attribute name'] = conveted value;
}
In syntax, replace {AttributeName} with your field name. But be careful and use camelcase for attribute name. For example if you want to define user_name then function name should be getUserNameAttribute for Accessor and setUserNameAttribute for Mutator.
Let's modify our model to set Accessor and Mutator for title attribute. So make below changes into Post Model :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'content',
'user',
];
public function getTitleAttribute($value)
{
return ucfirst($value);
}
public function setTitleAttribute($value)
{
$this->attributes['title'] = strtolower($value);
}
}
let's check our Accessor and Mutator function are working or not. Let's use controller to check it.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function checkAccessor(){
$post = Post::find(1);
echo $post->title;
exit;
}
public function checkMutator(){
$post = new Post();
$post->title = 'Foo Bar';
$post->content = "Test";
$post->user = "test";
$post->save();
echo $post;
exit;
}
}
let's define route too.
routes/web.php
<?php
use App\Http\Controllers\TestController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('check-accessor',[TestController::class,'checkAccessor');
Route::get('check-mutator',[TestController::class,'checkMutator');
Now we are ready to test our functionality. open terminal and run below command :
php artisan serve
Open this URL into browser and it will show location information.
http://127.0.0.1:8000/check-accessor
http://127.0.0.1:8000/check-mutator
When you open check-accessor then it will find first record and display it. While in check-mutator method, it will create new record form controller values.
Ask anything about this examples