TL; TR
Laravel 7.x에선 모델의 Property인 $casts에 커스텀된 클래스를 전달해줄 수 있다.[링크]
기존의 Mutators
Laravel 7.0의 공개 일자는 2020년 2월로 현재 얼마 남지 않은 상황에 laravel.com/doc/master에 차근차근 새로운 기능들에 대한 문서들도 업데이트 되는 것 같다.
이번에 getVarNameAttribute()
와 setVarNameAttribute($value)
를 사용하면서 mutator에 대한 커스텀은 안될까 하여 찾아보다가 master문서에 custom mutators 항목이 추가된 것을 발견하고 곧 7.0이 릴리즈 될테니 테스트겸 시도해보았다.
Laravel 7 dev 버전에 대한 설치는laravel new laravel7 --dev
또는 composer create-project --prefer-dist laravel/laravel:7.x-dev laravel7
으로 설치 할 수 있다.
$ cd laravel7
$ php artisan --version
Laravel Framework 7.x-dev
위와같이 artisan 명령어로 버전을 확인할 수 있다.
과거엔 welcome 템플릿에 laravel 7.0 (DEV) 🚀 라고 적혀있엇는데 아마 곧 공개를 앞으도 바뀐것같다.
++ User 테이블로 Custom mutator를 테스트 해보려고 하는데 laravel/ui 가 설치되지 않는다. 찾아보니 laravel7.x 부턴 laravel/ui에 login, register 등의 컨트롤러가 포함되어 배포되기에 laravel/ui 2.x를 설치해 줘야한다. composer requrie laravel/ui:2.x-dev --dev
기존에 mutators의 경우 array, datetime 등의 일부만 작동을 했고 만약 커스텀하게 짜기위해선 아래와 같이 해당 모델에 get, set~~Attribute 메소드를 짜줘야했다.
// App/User
public function getNameAttribute()
{
return "my name is {$this->name}";
}
public function setNameAttribute($value)
{
$this->name = ucfirst($value);
}
하지만 여러 테이블에서 사용될 때 반복되고 모델에도 만약 수정이 필요할 때 모델별로 다 수정해줘야하는 번거로움이 생긴다 (trait를 써도되지만 일단넘어가자..)
이번 Laravel 7.x 에선 Illuminate\Contracts\Database\Eloquent\CastsAttributes
클래스를 사용해서 datetime, array와 같인 $casts
프로퍼티에 지정할수있다.
App\Casts\Json
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class Json implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return array
*/
public function get($model, $key, $value, $attributes)
{
return json_decode($value, true);
}
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param array $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return json_encode($value);
}
}
App\User
<?php
namespace App;
use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'options' => Json::class,
];
}
위와 같이 CastsAttributes
클래스를 받고 해당 클래스를 $casts로 전달해주면 자동으로 맵핑해준다.
지금은 casts를 따로 생성하는 artisan명령어는 없는것같지만, laravel 7이 릴리즈되면 추가되지 않을까싶다.