Мутаторы

Содержание:


Введение

Аксессоры и мутаторы позволяют вам форматировать значения атрибутов Eloquent при получении или установки их для модели. Например, вы можете использовать шифровальщик Laravel, чтобы закодировать значение для хранения в базе данных и после автоматически расшифровывать при обращении к нему в качестве значения модели Eloquent.

Дополнительно к пользовательски аксессорам и мутаторам, Eloquent может автоматически преобразовывать значение атрибута в формате времени в экземпляры Carbon или даже преобразовывать в JSON.


Аксессоры и Мутаторы

Определение аксессора

Чтобы определить аксессор, создайте метод getFooAttribute для вашей модели, где составная часть имени Foo является именем столбца, к которому вы хотите получить доступ. В этом примере мы определим аксессор для атрибута first_name. Аксессор будет автоматически вызываться Eloquent при попытке получить значение атрибута first_name:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}

Как можно заметить, оригинальное значение столбца передается в аксессор, что позваляет вам проводить операции и вернуть значение. Чтобы получить доступ к значению аксессора, необходимо обратиться к атрибуту модели first_name:

$user = App\User::find(1);

$firstName = $user->first_name;

Вы можете использовать аксессоры, чтобы вернуть новые, составные значения из существующих атрибутов:

/**
 * Get the user's full name.
 *
 * @return string
 */
public function getFullNameAttribute()
{
    return "{$this->first_name} {$this->last_name}";
}
Если вы хотите добавить эти составные значение в массив / JSON представление вашей модели, вам необходимо добавить данные в JSON .

Определение мутатора

Чтобы определить мутатор, определим метод setFooAttribute для вашей модели, где Foo является именем столбца, к которому необходимо получить доспут. Поэтому, давайте определим мутатор для атрибута first_name. Этот мутатор будет автоматически вызываться при попытке установить значение для атрибута модели first_name:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Set the user's first name.
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}

Мутатор будет получать значение, которое было установлено для атрибута, позволяя вам манипулировать значением и устанавливать необходимое значение для внешнего Eloquent свойства модели Eloquent. Например, если мы пытаемся установить атрибут first_name как Sally:

$user = App\User::find(1);

$user->first_name = 'Sally';

В этом примере, функция setFirstNameAttribute будет вызвана со значением Sally. Уже после мутатор использует функцию strtolower для имени и установит конечное значение во внутренний массив $attributes.


Мутаторы времени

По умолчанию, Eloquent будет преобразовывать столбцы created_at и updated_at в экземпляры Carbon, которые расширяют класс PHP DateTime и предоставляет набор полезных методов. Вы можете добавить дополнительные атрибуты времени путём установки свойства $dates для вашей модели:

<?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',
    ];
}
Вы можете отлкючить базовые метки времени created_at и updated_at путём установки значения false для публичного свойства $timestamps.

Когда столбец считается датой, вы можете установить тип значения как: метки времени UNIX, строка времени (Y-m-d), или экзмемпляр DateTime / Carbon. Такие значения будут верно преобразовываться и храниться в вашей базе данных:

$user = App\User::find(1);

$user->deleted_at = now();

$user->save();

Как было упомянуто выше, при получении атрибутов, которые перечислены в вашей свойстве $dates, они будут автоматически преобразованы в экземпляры Carbon, позволяя вам использовать любые методы Carbon для ваших атрибутов:

$user = App\User::find(1);

return $user->deleted_at->getTimestamp();

Форматы дат

По умолчанию, временные метки форматированы как 'Y-m-d H:i:s'. Если вам нужна настройка формата меток, установите свойство $dateFormat для вашей модели. Это свойство определит, как атрибуты даты хранятся в базе данных, также как и их формат, когда модель сериализуется в массив или JSON:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * The storage format of the model's date columns.
     *
     * @var string
     */
    protected $dateFormat = 'U';
}

Преобразование атрибутов

Свойство $casts для вашей модели предоставляет удобный метод для преобразования атрибутов в обычные типы данных. Свойство $casts должно быть массивом, где ключ является именим передаваемых атрибутов, а значение является типом, который бы вы хотели назначить столбцу. Список поддерживаемых типов: integer, real, float, double, decimal:<digits>, string, boolean, object, array, collection, date, datetime, и timestamp. При использовании типа decimal, вы должны определить число знаков после запятой (decimal:2).

Для демонстрации трансляции атрибутов, давайте преобразуем атрибут is_admin, который хранится в вашей базе данных как целое число (0 или 1) в логическое значение:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'is_admin' => 'boolean',
    ];
}

Теперь атрибут is_admin будет всегда преобразовываться в логическое при запросе доступа, даже если значение базе данных является числом:

$user = App\User::find(1);

if ($user->is_admin) {
    //
}

Преобразование массива и JSON

Массив преобразования array может быть особенно полезным при работе со столбцами, которые хранятся как сериализованный JSON. Например, если у вашей базы данных есть столбцы с типами JSON или TEXT, которые хранят сериализованный JSON. Если добавить преобразование в массив array для атрибута, то мы автоматически проведём десериализацию атрибута в массив PHP при запросе модели Eloquent:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'options' => 'array',
    ];
}

После определения преобразования, вы можете получить доступ к атрибутам options, и они автоматически будут десериализованы из JSON в массив PHP. Когда вы устанавливаете значение для атрибута options, данных массив будут автоматически сериализован обратно в JSON для хранения в бд:

$user = App\User::find(1);

$options = $user->options;

$options['key'] = 'value';

$user->options = $options;

$user->save();

Преобразование времени

При использовании типа преобразования date или datetime, вы можете указать формат времени. Этот формат и будет использован, когда модель сериализуется в массив или JSON:

/**
 * The attributes that should be cast to native types.
 *
 * @var array
 */
protected $casts = [
    'created_at' => 'datetime:Y-m-d',
];