Home > OS >  What is the difference between Accessor/Mutators and Casting in laravel?
What is the difference between Accessor/Mutators and Casting in laravel?

Time:12-26

What is the difference between Accessor/Mutators and Casting in laravel?

<?php
...
class User extends Model
{

        public function getIsAdminAttribute($value){
                return (bool)$value;
        }

        public function setIsAdminAttribute($value){
                $this->attributes['is_admin'] = (bool)$value;
        }
}

..

<?php
...
class User extends Model
{
        protected $casts = [
            'is_admin' => 'boolean',
        ];
}

I feel like they are both doing the same thing so what is the difference?

CodePudding user response:

An accessor transforms an Eloquent attribute value when it is accessed.

public function getFirstNameAttribute($value)
{
   return strtoupper($value);
}

Whenever you fetch a model, the property will be formatted/returned as per the accessor definition. Let's assume that a user's first_name is John. The above accessor will return the first_name in uppercase:

$user = User::findOrFail($id);
dd($user->first_name); // Will return 'JOHN' instead of 'John' because accessor

In the opposite way, a mutator will handle the property before being stored in your database

public function setFirstNameAttribute($value)
{
   $this->attributes['first_name'] = strtoupper($value);
}

Whenever you save a model, the property will be formatted as per the mutator definition. Let's assume that you pass a user's first_name as John. The above mutator will transform the first_name as JOHN before store:

$user = new User();
$user->first_name = 'John'; // It will be stored as JOHN because mutator
$user->save();

The attribute casting provides functionality similar to accessors and mutators. The main purpose is for using predefined casting methods instead of manually defining your own ones. IE, creating a date Carbon instance from a property:

protected $casts = [
    'birthday' => 'date',
];

Instead of

public function getBirthdayAttribute($value)
{
   return Carbon::create($value);
}

public function setBirthdayAttribute($value)
{
   $this->attributes['birthday'] = Carbon::create($value);
}

You can check docs at https://laravel.com/docs/8.x/eloquent-mutators#attribute-casting

CodePudding user response:

In addition to what Luciano wrote, accessors and mutators can do things that casting cannot. In the example below, we define a is_birthday attribute.

/**
 * @property Carbon date_of_birth
 * @property-read boolean is_birthday
 */
class Person extends Model {
  public function getIsBirthdayAttribute(){
    return $this->attributes['date_of_birth']->isToday();
  }
}

These derived attributes can be really helpful to abstract away common access patterns, like getting a full name from first and last names or computing invoice (sub)totals.

  • Related