이번 포스트에서는 라라벨 Livewire 환경에서,
- 유효성 검사 코드를 깔끔하게 분리하고 재사용성을 높여주는 '폼 객체(Form Object)' 도입 방법
- 개발 중 우연히 발견한 어떤 에러를 해결한 방법
을 정리해 보겠다.
이전 포스트
라라벨 filament, 관리자 메뉴 아이콘 변경, 순서 정렬 및 그룹화 방법
유효성 검사 코드를 ArticleForm으로 이동 · 4th-avenue/laravel13-livewire@bebd074 · GitHub
전체적인 코드 수정은 이 깃허브 링크를 통해 확인하자.
유효성 검사와 글 저장 로직을 분리하기 위한 ArticleForm 생성
make bash #컨테이너 안으로 들어간다.
php artisan livewire:form ArticleForm
ubuntu 혹은 VSCode의 터미널에서 이 명령어들을 실행한다.
위의 명령어는 폼 관련 데이터와 검증(Validation) 로직을 별도로 분리해 깔끔하게 관리하는 폼 객체(Form Object) 클래스를 생성하는 명령어다.
실행하면, app/Livewire/Forms 디렉터리 안에서 ArticleForm.php 파일이 생긴다.
기존의 Livewire 컴포넌트 클래스 안에는 여러 가지 프로퍼티와 유효성 검사 코드와 글을 저장하는 메서드들이 한데 섞여 코드가 길어지기 쉬웠다.
그런데 Form Object를 사용하면 폼에 들어갈 입력 필드, 유효성 검사 규칙, 저장・수정 로직을 하나의 클래스 안에 캡슐화하여 묶어둘 수 있다.
새 글 작성 페이지와 수정 페이지처럼 동일한 입력 폼 구조와 검증 규칙을 사용하는 경우, ArticleForm 하나를 두 컴포넌트에서 그대로 재사용할 수 있다.
그러면 메인 컴포넌트 코드의 양이 줄어서 가벼워지고, 폼 검증・저장 로직을 한 곳에서 안전하고 깔끔하게 관리할 수 있다는 장점이 있다.
Forms | Laravel Livewire
오늘의 포스트와 관련된 Livewire 공식 문서의 링크다.
이 포스트에서는 글Article의 저장・수정 로직은 Livewire 컴포넌트에 그대로 두고, 폼에 들어갈 입력 필드와 유효성 검사 코드만 ArticleForm으로 옮겨보도록 하겠다.
더 자세한 내용은 공식 문서를 참고하자.
유효성 검사 코드를 ArticleForm으로 이동
app/Livewire/Forms/ArticleForm.php
class ArticleForm extends Form
{
#[Validate('required|exists:categories,id')]
public int $category_id;
#[Validate('required|string|max:60')]
public string $title;
#[Validate('required|string|max:21844')]
public string $body;
}
ArticleForm.php의 클래스 안에 이렇게 프로퍼티들과 유효성 검사 규칙을 넣도록 하자.
이 코드들은 새로운 코드가 아니라 이전에 만들어둔 ⚡new.blade.php와 ⚡edit/edit.php 안에 있던 코드들을 그대로 가져온 거다.
더 정확히는 ⚡edit/edit.php의 유효성 검사 코드를 가져온 거다.
⚡new.blade.php에서는 프로퍼티에 데이터 타입(int, string 등)을 명시하지 않았었다.
라라벨 Livewire로 새 글 작성 시 유효성 검사 기능 구현
라라벨 Livewire 4, 글 수정 기능 구현
이 유효성 검사 코드에 대해서는 이 포스트들을 참고하자.
기존의 Livewire 컴포넌트 수정
public ArticleForm $form;
⚡new.blade.php와 ⚡edit/edit.php에 있었던 프로퍼티 선언과 유효성 검사 코드들을 삭제하고, 거기에 이 코드를 넣는다.
이 코드로 인해 ⚡new.blade.php와 ⚡edit/edit.php는 ArticleForm 객체를 주입받는다.
$this->form->fill($this->article->only(['category_id', 'title', 'body']));
이제부터 설명하는 코드들은 필히 포스트 상단의 깃허브 링크를 참고해야 한다.
왜냐하면 수정해야 할 곳이 너무 많아서 수정할 코드 중에 딱 하나만 가져왔기 때문이다.
이제 ⚡new.blade.php와 ⚡edit/edit.php와 ⚡edit/edit.blade.php에서는 ArticleForm을 폼 객체(public ArticleForm $form;)로 주입했기 때문에, 컴포넌트 클래스와 Blade 뷰에서 form->과 form. 접두사를 맞춰줘야 정상적으로 작동한다.
포스트 상단의 깃허브 링크에서 코드 변화를 보면 무슨 말인지 바로 이해할 수 있을 거다.
고쳐야 할 곳이 10곳이 훌쩍 넘으니 꼼꼼하게 살펴보고 수정하자.
이렇게 해서 Livewire의 폼 관리를 보다 객체 지향적으로 만들고, 각 폼의 상태와 메서드를 개별 객체로 캡슐화할 수 있게 되었다.
오늘의 포스트에서는 새롭게 추가된 기능도 없고, 겉으로 뭔가 바뀌었다는 변화도 없다.
하지만 내부에서는 컴포넌트 클래스가 조금 더 슬림해졌고, 유효성 검사 규칙을 재사용함으로써 유지보수성이 향상됐고, 역할 분리도 명확해졌다.
우연히 발견한 에러 수정
이렇게 ArticleForm을 만들고 역할을 나누면서 테스트를 하던 도중에 에러를 하나 발견했다.
캡처한 이미지와 함께 설명하겠다.
새 글을 작성할 때, 일단 카테고리도 선택하고, 제목과 본문의 내용을 써넣었다.
그런데 일부러 유효성 검사에 한번 걸리게 하기 위해서 제목의 글자수를 초과해서 넣어보았다.
그러면 당연히 이렇게 글자수를 초과했다는 에러 메시지가 표시된다.
그런데 글을 다시 수정할 때, 일부러 처음에는 제대로 선택했었던 카테고리를 '카테고리를 선택하세요.'로 변경해 보았다.
그러고 나서 저장 버튼을 클릭하면?
이런 에러가 뜨게 된다.
이런 짓을 할 사용자는 좀처럼 없겠지만, 어쨌든 내가 우연히 이걸 발견한 것처럼 누군가는 이런 에러를 발견하게 될지도 모른다.
이런 에러가 사용자에게 뜨는 것은 반드시 고쳐야 한다.
resources/views/pages/articles/⚡new.blade.php
<option value="">{{ __('Select a category.') }}</option>
'카테고리를 선택하세요.'라는 텍스트를 표시하는 이 옵션에 value 속성으로 빈 값을 넣으면 된다.
value 속성이 없었을 때는 에러가 발생했던 이유는, HTML 표준상 <option> 태그에 value 속성이 아예 없으면, 브라우저는 태그 사이에 있는 텍스트(예: Select a category.)를 그대로 값으로 인식해서 서버로 전송한다.
결국 정수형(int)이어야 할 category_id 프로퍼티에 숫자 ID 대신 문자열 텍스트가 그대로 들어와서 에러가 발생한 것이다.
수정 후에는 선택했던 카테고리를 일부러 이렇게 '카테고리를 선택하세요.'로 변경해서 저장을 시도하면, 목록에서 항목을 선택하라고 뜨면서 에러는 발생하지 않게 된다.
Mission complete!!
이 글은 월요일 아침에 예약 발행이 되겠지만, 지금 이 글을 다 완성한 시각은 일요일 새벽 2시다.
나의 이 고생을 언젠가는 누군가 알아주고, 이 콘텐츠가 빛을 발하는 날이 오겠지.
다음 포스트



0 Comments
댓글 쓰기
🔸 댓글은 블로그 운영자의 승인 후에 블로그에 표시됩니다.
🔸 비로그인 방문자 분께서는 '익명'보다 이름/URL로 댓글을 남겨주시면 감사하겠습니다. (URL은 생략 가능합니다.)
🔸 구글 로그인 방문자는 '알림 사용'에 체크를 하시면, 남겨주신 댓글에 대한 답글 알림을 메일로 받아볼 수 있습니다. 📩