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이 릴리즈되면 추가되지 않을까싶다.