Error기록 노트/PHP | Laravel

[Laravel] Model의 casts, guarded, fillable는 언제 쓰는가?

에러노트 2023. 9. 27. 17:10

안녕하세요. 에러노트입니다.

오늘은 별안간 기초로 돌아왔습니다.

바쁘게 작업 중 평소 '그냥 써야해서 썼는데, 왜 써야하는지'는 정확히 모르는 model의 몇가지 속성을 정리해보고자 합니다.

+) 그리고 제가 두가지를 왜 쓰는지 몰라 만났던 이슈와 에러도 함께 살펴보겠습니다.


 

0. Model에서 해당 구문을 왜 쓰는지 설명할 수 있나요?

아래 구문의 $guarded or $fillable, $casts를 왜 쓰는지 알고 계신다면 바로 뒤로가기를 누르세요.

오늘은 이 친구를 도대체 왜 써야하는가?에 대해 알아보고자 합니다.

class Notification extends Model
{
    protected $guarded = [];

    protected $casts = [
        'open_date' => 'date',
        'close_date' => 'date',
    ];
}

지금까지 써야지 문제가 안생긴다는 말을 듣고, 이유를 모른 채 써왔습니다만, 여러분은 명확하게 알고 계신가요?

사실 이런 경우가 비단 굉장히 많죠. 그러다보니 명확하게 알지 못하고 쓰면서 자연르세 에러가 발생하곤 합니다..😂

(그게 접니다 빠밤!) 그래서 정리해보았습니다.

1. $fillable와 $guarded를 왜 쓰는가?

첫번쨰는 보안 떄문입니다. 대량 할당으로부터 보호하기 위한 설정으로,

$fillable대량 할당을 허용하는 값을 배열로 설정한다면,

$guarded대량 할당을 허용하지 않고 보호한다는 차이점이 있습니다.

여기서 '대량 할당' 여러 속성 값을 동시에 설정하는 것을 말합니다. 배열이나 객체를 사용하여 여러 속성을 한 번에 설정할 수 있습니다.

 

2. $casts는 언제 쓰는가?

casts는 데이터를 일관된 형식으로 다루고 변환할 수 있으며, 모델의 속성을 사용할 때 편리한 친구입니다.

주로 쓰이는 경우는 다음과 같다.

 1) json을 배열 형식으로 변환하고자 할 때

 2) 정수 값을 boolean으로 변환하여 ture/false로 쓸 때

 3) 날짜 및 시간을 DateTime 객체로 변환하여 사용하고자 할 때

 4)본인이 정의한 데이터 형식(사용자 설정)으로 변환 할 때


3. 잘 몰라서 생겼던 이슈와 에러

[당시 환경 셋팅]

 Laravel 8,  Laravel Nova, Homebrew, Valet, Mysql, Vue.js, Inertia.js

당시 저는 릴레이션을 짜고 있어서 모델과 마이그레이션, nova resource를 생성중이었습니다.

그 중 uuid를 id로 설정하여 BelongsToMany 관계로 애를 먹고 있었고, pivot 관계와 함께 사용하면서 nova에서 아래 에러가 반복적으로 나타났습니다.

count(): Argument #1 ($value) must be of type Countable|array, string given
//첫 번째 인수가 Countable 유형이거나 배열 (array) 유형이어야 하며, 그러나 대신에 문자열 (string)이 전달되었습니다.

해당 문제의 원인을 일주일간 찾은 결과,

바로 $fillable과 datetype의 설정, belongsToMany의 id 인자값 설정 문제였습니다.

class User extends Model
{
	use HasRoles;
 	use HasUuid;
    
    protected $keyType = 'string';
    
    protected $fillable = [];
    
    public function program():BelongsToMany {
        return $this->belongsToMany(Program::class,'user_Program','user_id','program_id')
            ->withPivot(['status','professor'])
            ->using(UserProgram::class);
    }
    ...
}

$keyType을 문자열로 적고 $fillable을 배열로 작성하였기 때문에 문제가 되었던 것입니다.

$fillabledmf tkrwpgkrh $guarded = [];로 수정하고야 비로소 해결되었습니다.

추가로 BelongsToMany의 id의 순서도 양쪽 다 동일하게 작성하여 문제가 생겼었는데, 이부분은 아직 더 공부해야 할 것 같습니다.


결국 마지막의 이슈도 이해 없이 쓰는 코드로 인해 생겼던 헤프닝이죠..😭

대량할당 이전에 타입을 신경써야한다는 점까지...또 하나 배웠습니다!

여러분들도 이런 경험이 있다면 알려주세요 😉

긴 연휴 잘 보내시고, 일교차가 점점 벌어지는만큼 건강 유의하시길 바랍니다. :)