Laravel 4 Accessors & Mutators

Eloquent provides a convenient way to transform your model attributes when getting or setting them. In Laravel 3 they were called Getter & Setter Methods. In Laravel 4 they are called Accessors & Mutators.

Accessors are custom methods in your Model that modify the value of a field before it is returned to you (e.g. before you display it on screen). Similarly, mutators are custom methods in your Model that modify the value of a field prior to being set (e.g. before being saved to database ). These methods are called automatically when you access or set the field as a property on the model (e.g. $movie->release_date).

Note: Laravel 4 adheres to the PSR-0 standard so the accessors / mutators’ method names have to be CamelCase. So, if you have an attribute called “release_date”, the appropriate mutator has to be called setReleaseDateAttribute() and the appropriate accessor has to be called getReleaseDateAttribute(). But enough of theory, let’s see an example.

Modifying date attribute with Accessors & Mutators

Let’s suppose we have a table “Movies”. The table has various fields like title,length, studio etc and of course release_date field (date). What we want to do is automatically modify/format release_date field before inserting it into database and before displaying it in our form. Now this is just for example but let’s suppose that in the database it is stored in Y-m-d format (2013-06-16) and in our form it has d/m/Y format (16/06/2013). I am using Carbon class for date conversion (you can find it in vendor/nesbot/carbon folder – it is included with Laravel 4) but you can use anything you like – even PHP date().

So open your Movies.php model (that extends Eloquent) and add this method somewhere:

//mutator for changing date d/m/Y format to Y-m-d format so it can be stored in database
 public function setReleaseDateAttribute($value)
        $this->attributes['release_date'] = Carbon::createFromFormat('d/m/Y', $value)->toDateString();

This might look complicated at first but don’t worry, it isn’t. As you can see we have a mutator method (setReleaseDateAttribute). If you are wondering why does this method have such name then please re-read the third paragraph of this post (about PSR-0 standard). Note that the value of the attribute is passed to mutator.

Let’s explain this line:


We access the attribute “release_date” with $this->attributes['release_date'] and set/change it to whatever we want. In the right part we are using Carbon class to create ‘d/m/Y’ variable with $value and then convert it to Y-m-d format with Carbon’s toDateString() method. Again, read Carbon documentation. The right part can be anything you want :

 $this->attributes['release_date'] = '2013-06-13';

Of course that would manually set the date and ignore the actual $variable so this is just for demonstration.

Accessor works the same way, except that we use “get” instead of “set” in the method name. Also since it is just accessor we do not modify the $this->attributes['release_date'] – we just return a (new) value. So add this code below mutator code in your model:

//accessor for changing date Y-m-d format to d/m/Y format so it can be displayed in form field
 public function getReleaseDateAttribute($value). 
       return Carbon::createFromFormat('Y-m-d', $value)->format('d/m/Y');

As you can see we return the value with return and in the mutator we don’t – in mutator we set/modify the $this->attributes['release_date'] .(Also Carbon statement is a little different)

How does Laravel automatically know when to use accessor and when mutator?

If we access the variable somewhere in our controller or model (like $var = $movie->release_date;) then Laravel will call accessor before it is returned to us. If we set the variable (like $movie->release_date = "16/06/2013";) and then save it to database ( e.g. $movie->save() ) Laravel will call mutator before it is saved to database.

Note: If you want to use Carbon class that is included with Laravel 4 you can autoload it or simply add use Carbon\Carbon; right at the top of your model so it looks something like this:


use Carbon\Carbon;

class Movies extends Eloquent {
//your code, accessors and mutators here