Attributes casting, accessors, and mutators in laravel

Eloquent has many ways to transform the model data into something more readable or usable (and vice versa). In this article, we are going to analyze three of them: attributes casting, accessors, and mutators.

Attributes casting

The easier way to transform your model attributes while accessing them is the attributes casting. In a few words, it lets you define what attribute you want to cast and what is going to be the destination type.

Suppose that you have another integer field in your books table: is_rare. If the book is rare, this will be equal to 1, 0 otherwise. However, when you work with it, the best thing would logically be as follows:

  if($book->is_rare)
  {
    // do wow things here...
  }
  else
  {
    // do common things here...
  }

It will not be something like this:

  if($book->is_rare === 1)
  {
    // ...
  }

Right? Good.

So, all you have to do to fix this problem is to specify, in your model, the casts array:

  <?php // Book.php

  namespace App;

  class Book extends Model {

    protected $casts = [
        'is_rare' => 'boolean',
    ];

  }

From this moment, every time you call the is_rare attribute, it will be automatically converted to the Boolean corresponding value and returned.

The supported types for casting are: integer, real, float, double, string, Boolean, object, and array.

Note

As also the documentation suggests, the array casting type is useful when you have a JSON array stored in a specific table column and you want to work with it quickly.

Accessors and mutators

Attributes casting is very useful but has some limitations. Sometimes, starting from a simple value stored in the database, you need to do more complex work on it. Accessors and mutators are here to help.

To be more specific, an accessor is a method that is executed when the user reads a specific attribute. The accessor works on the attribute stored in the database and returns it. A mutator works in the opposite way: when you store a value, the mutator works, does its job and then saves it in the table. Let’s say they are sorts of getters and setters.

Defining an accessor (or a mutator) is not so difficult: all you have to do is to follow a naming convention.

Let’s start with something simple. Imagine that every time that you access the price of your book, you want to put the dollar symbol $ at the beginning of the string.

  <?php // Book.php

    namespace App;

    class Book extends Model {

      public function getPriceAttribute()
        {
            return '$ ' . $value;
        }

    }

The naming convention for an accessor is simple as shown:

  • The method name starts with get
  • The middle part of the name is the attribute name, which is camel cased
  • The method name ends with Attribute

Nothing more.

Now, have a look at this:

  $book = AppBook::find(1);

  echo $book->price;
  // output: $ 10.50

Every time you have the preceding code, the mutator is very similar. This time, we want to store a lowercase version of the title.

  <?php // Book.php

    namespace App;

    class Book extends Model {

      public function setTitleAttribute($value)
        {
            $this->attributes['title'] = strtolower($value);
        }

    }

The convention isn’t changed so much: the only difference is that the method name now starts with set and not get. It’s all about getters and setters, my friend.

Another real common use of mutators is when the application stores the user’s password. A mutator can be used to hash the chosen password and the result is then stored.

  <?php // User.php

    namespace App;

    class User extends Model {

      public function setPasswordAttribute($value)
        {
            $this->attributes['password'] = Hash::make($value);
        }

    }

About the author

Deven Rathore

I'm Deven Rathore, a multidisciplinary & self-taught designer with 3 years of experience. I'm passionate about technology, music, coffee, traveling and everything visually stimulating. Constantly learning and experiencing new things.

  • leonel

    Do you know how do I can have a mutator for an array input like user.*.firstname

Pin It on Pinterest

Shares