Accessors and Murators allow you to format Eloquent properties when we retrieve or add new models. For example, when adding a user you want before adding, it automatically encrypts the value of the password before being saved to the database or retrieving a name from the database as a print. flowers then accessors
and murators
will help us to do this. In addition, Eloquent can also automatically convert the date field into a Carbon instance or convert a text into a json data type.
A little briefly accessors
will help us format the data when we get data from the database. Suppose we have a field name
in a table user
and want it to be capitalized when retrieving data. First we need to create a method to define this in the model User
as get
+ field name in uppercase letters
+ Attribute
. In this case the method written will be getNameAttribute
.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
public function getNameAttribute($value)
{
return strtoupper($value);
}
}
Now try to see how the result looks like, you will create one route
as follows:
Route::get('/accessors', function() {
$user = App\User::find(1);
return $user->name;
});
Now go to localhost: 8000 / accessors and see the results.
Or you can even define a new property with existing attributes, for example:
public function getFullNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
The procedure is similar
$user->fullname;
Other than that, accessors
it is murators
used to format data before saving it into a database. To define a murators
similarity with accessors
just another is the prefix would be set
. For example, we will format the field name
to non-capitalized before saving it to the database. So the method here will besetNameAttribute
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
public function setNameAttribute($value)
{
$this->attributes['name'] = strtolower($value);
}
}
To test we also create a route with the following content:
Route::get('/murators', function() {
$user = App\User::find(1);
$user->name = "CCC";
$user->save();
return $user->name;
});
To check the data saved correctly or not to open php artisan tinker
up to the test App\User::find(1)
, we will see the value of the name
medium will be saved ccc
.
By default, Eloquent will automatically convert two fields created_at
and update_at
into a Carbon instance, and it provides a lot of useful functions. We can also add date attributes using the $date
model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'seen_at',
];
}
When a field is of type date
you can set its value as a UNIX timestamp
, date string (Ymd), date-time string or an instance of Carbon, and the value of the date will automatically be stored in the database.
By default the timestamps are formatted Y-m-d H:i:s
, you can customize this format by using the attribute dateFormat
in the model, which will reformat as the date data type to be stored in the database.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $dateFormat = 'Y-m-d';
}
Attributes $cast
help convert attributes to normal data types. The property $cast
is usually an array with the key being the name of the property to be transferred and value being the type of data you want to convert. The type of data that the attribute $cast
supports: integer, real, float, double, decimal:<digits>, string, boolean, object, array, collection, date, datetime, and timestamp
. For example, we have the attribute is_admin
stored in the database is 0
and 1
with the data type integer
but you want to use it as the data type boolean
, do the following
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $casts = [
'is_admin' => 'boolean',
];
}
We then use it is_admin
as a property of data typeboolean
$user = App\User::find(1);
if ($user->is_admin) {
}
You can define an attribute cast
for your own by creating an implements class from the CastsAttributes
interface. One thing to note is that this newly created class must exist two methods get
and set
with different tasks. The method is get
used to convert data in the database to the data type cast
you define, and the method set
has the opposite task to convert the converted data into the original data type to store in the database. For example, we custom attribute cast
is json data type.
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class Json implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
{
return json_decode($value, true);
}
public function set($model, $key, $value, $attributes)
{
return json_encode($value);
}
}
Then we will use it in the model.
<?php
namespace App;
use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $casts = [
'options' => Json::class,
];
}
Cast
The array type is useful when we use them with columns stored as json.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $casts = [
'options' => 'array',
];
}
When declared like this, we will use and process the data as an array in PHP. When you set a value for a property options
, the given array is automatically converted back into JSON for storage:
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();
When used cast
with date and datetime data types, we can reformat for this data type
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];
Sometimes you can use both cast
in queries
use App\Post;
use App\User;
$users = User::select([
'users.*',
'last_posted_at' => Post::selectRaw('MAX(created_at)')
->whereColumn('user_id', 'users.id')
])->get();
The property is last_posted_at
based on the result of the selectRaw statement, which makes sense if we set the data type to last_posted_at
a date type, simply by using the method withCasts
.
$users = User::select([
'users.*',
'last_posted_at' => Post::selectRaw('MAX(created_at)')
->whereColumn('user_id', 'users.id')
])->withCasts([
'last_posted_at' => 'date'
])->get();
You can also see how other useful properties this cast
brings here .
#php #laravel