Eloquent Mutators and Accessors in Laravel
In this article, we'll go through mutators and accessors of the Eloquent ORM in the Laravel web framework. After the introduction, we'll go through a handful of examples to understand these concepts.
In Laravel, mutators and accessors allow you to alter data before it's saved to and fetched from a database. To be specific, the mutator allows you to alter data before it's saved to a database. On the other hand, the accessor allows you to alter data after it's fetched from a database.
In fact, the Laravel model is the central place where you can create mutator and accessor methods. And of course, it's nice to have all your modifications in a single place rather than scattered over different places.
Create Accessors and Mutators in a Model Class
As you're familiar with the basic concept of mutators and accessors now, we'll go ahead and develop a real-world example to demonstrate it.
I assume that you're aware of the Eloquent model in Laravel, and we'll use the Post model as a starting point of our example. If you haven't created the Post
model yet, let's use the artisan
command to create it.
php artisan make:model Post --migration
That should create a model file at app/Post.php
as shown below.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { // }
Let's replace the contents of that file with the following.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = [ 'created_at', 'updated_at', 'published_at' ]; /** * Get the post title. * * @param string $value * @return string */ public function getNameAttribute($value) { return ucfirst($value); } /** * Set the post title. * * @param string $value * @return string */ public function setNameAttribute($value) { $this->attributes['name'] = strtolower($value); } }
As we've used the --migration
option, it should also create an associated database migration. Just in case you are not aware, you can run the following command so that it actually creates a table in the database.
php artisan migrate
In order to run examples in this article, you need to create name
and published_at
columns in the post
table. Anyway, we won't go into the details of the migration topic, as it's out of the scope of this article. So we'll get back to methods that we are interested in.
Firstly, let's go through the mutator method.
/** * Set the post title. * * @param string $value * @return string */ public function setNameAttribute($value) { $this->attributes['name'] = strtolower($value); }
As we discussed earlier, the mutators are used to alter data before it's saved to a database. As you can see, the syntax of the mutator method is set{attribute-name}Attribute
. Of course, you need to replace {attribute-name}
with an actual attribute name.
The setNameAttribute
method is called before the value of the name
attribute is saved in the database. To keep things simple, we've just used the strtolower
function that converts the post title to lowercase before it's saved to the database.
In this way, you could create mutator methods on all columns of your table. Next, let's go through the accessor method.
If mutators are used to alter data before it's saved to a database, the accessor method is used to alter data after it's fetched from a database. The syntax of the accessor method is the same as that of the mutator except that it begins with the get keyword instead of the set keyword.
Let's go through the accessor method getNameAttribute
.
/** * Get the post title. * * @param string $value * @return string */ public function getNameAttribute($value) { return ucfirst($value); }
The getNameAttribute
method will be called after the value of the name attribute is fetched from the database. In our case, we've just used the ucfirst
method to alter the post title.
And that's the way you are supposed to use accessors in your models. So far, we've just created mutator and accessor methods, and we'll test those in the upcoming section.
Mutators in Action
Let's create a controller at app/Http/Controllers/MutatorController.php
so that we can test the mutator method that we created in the earlier section.
<?php // app/Http/Controllers/MutatorController.php namespace App\Http\Controllers; use App\Post; use App\Http\Controllers\Controller; class MutatorController extends Controller { public function index() { // create a new post object $post = new Post; $post->setAttribute('name', 'Post title'); $post->save(); } }
Also, you need to create an associated route in the routes/web.php
file to access it.
Route::get('mutator/index', 'MutatorController@index');
In the index
method, we're creating a new post using the Post
model. It should set the value of the name column to post title as we've used the strtolower
function in the setNameAttribute
mutator method.
Date Mutators
In addition to the mutator we discussed earlier, the Eloquent model provides a couple of special mutators that allow you to alter data. For example, the Eloquent model in Laravel comes with a special $dates
property that allows you to automatically convert the desired columns to a Carbon
date instance.
In the beginning of this article, we created the Post
model, and the following code was part of that class.
... ... /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = [ 'created_at', 'updated_at', 'published_at' ]; ... ...
As you probably know, Laravel always creates two date-related fields, created_at
and updated_at
, with each database migration. And it converts those values to a Carbon
date instance as well.
Let's assume that you have a couple of fields in a table that you would like to treat as date fields. In that case, you just need to add column names in the $dates
array.
As you can see in the above code, we've added the published_at
column in the $dates
array, and it makes sure that the value of that column will be converted to a Carbon
date instance.
Accessors in Action
To see accessors in action, let's go ahead and create a controller file app/Http/Controllers/AccessorController.php
with the following contents.
<?php namespace App\Http\Controllers; use App\Post; use App\Http\Controllers\Controller; class AccessorController extends Controller { public function index() { // load post $post = Post::find(1); // check the name property echo $post->name; // check the date property echo $post->published_at; // as we've mutated the published_at column as Carbon date, we can use following as well echo $post->published_at->getTimestamp(); exit; } }
Also, let's create an associated route in the routes/web.php
file to access it.
Route::get('accessor/index', 'AccessorController@index');
In the index
method, we've used the Post
model to load an example post in the first place.
Next, we're inspecting the value of the name column, and it should start with an uppercase letter as we've already defined the accessor method getNameAttribute
for that column.
Moving further, we've inspected the value of the published
_at
column, and that should be treated as a date. Due to that, Laravel converts it to a Carbon instance so that you can use all the utility methods provided by that library. In our case, we've used the getTimestamp
method to convert the date into a timestamp.
And that brings us to the end of this article!
Conclusion
Today, we've explored the concepts of mutators and accessors of the Eloquent ORM in Laravel. It provides a nice way to alter data before it's saved to and fetched from a database.
For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.
Don't hesitate to share your thoughts using the feed below!
from Envato Tuts+ Tutorials
Comments
Post a Comment