Laravel eloquent and accessor with example

In this Blog, we’ll understand mutators and accessors of the Eloquent ORM in the Laravel framework by examples.

Laravel, Accessors, and Mutators allow us to alter data while saving and fetching. As per the name, the Accessor alters data while accessing and Mutators modify data while saving. The major difference between an accessor and a Mutator is that data modification in an accessor is temporary while in a mutator modified data is stored in the database.

For example, if we want to store a user name in upper case in our database then we can define a mutator for that so that when we save the model it will automatically convert the name into uppercase and also store the 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 them manually Right!!! But by using accessors we can create an attribute that merges it and use that attribute whenever required.

Create Accessors and Mutators in a Laravel Model

Let’s take a practical example. Here, we will create a Post Model and define the Accessor and Mutator on it.

To create a model, enter the below command into your terminal:

php artisan make:model Post -m

It will create a Model and migration file for Post. Let’s modify them one by one:

<?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',
    ];
}
<?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');
    }
}

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 in lowercase using Mutator and use the title in title case while displaying using accessors.

Here, we have created a basic database structure for our posts table now it’s time to migrate it. Enter the below command to migrate :

php artisan migrate

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 the Accessor will convert the 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 the attribute name. For example, if you want to define user_name then the function name should be getUserNameAttribute for Accessor and setUserNameAttribute for Mutator.

Let’s modify our model to set Accessor and Mutator for the title attribute. So make the 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);
    }
}

Checking Accessor and Mutator

Let’s check whether our Accessor and Mutator functions are working or not. Let’s use a 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 the route too.

<?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');

Testing our Functionality

Now we are ready to test our functionality. open the terminal and run the below command :

php artisan serve

Open this URL in a 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 the check-accessor then it will find the first record and display it. While the check-mutator method will create new records from controller values.