Laravel Livewire, 개별글 표시하기 (라우트 모델 바인딩)

포스트 썸네일 이미지

이번 포스트에서는 글 목록 페이지의 제목을 클릭했을 때 개별 게시글 상세 페이지로 이동하고, 해당 글의 내용을 화면에 표시하는 과정을 다뤄보겠다.

글 목록 페이지를 만들었을 때처럼 디자인은 크게 신경쓰지 않을 거다.

기능에만 집중하도록 하자.




이전 포스트




전체적인 코드 수정은 이 깃허브 링크를 통해서 확인할 수 있다.




Livewire 컴포넌트 pages::articles.show 생성 (--mfc 옵션)


make bash #컨테이너 안으로 들어간다.
php artisan make:livewire pages::articles.show --mfc

ubuntu 혹은 VSCode의 터미널에서 이 명령어들을 실행한다.

이번에는 처음으로 --mfc 옵션을 넣어보았다.


그러면 resources/views/pages/articles 디렉터리에 /⚡show 디렉터리가 생긴다.

그리고 그 안에 show.blade.php와 show.php, 2개의 파일이 생성된다.




자세한 내용은 이 포스트를 참고하자.





routes/web.php에서 라우팅 설정하기


routes/web.php

Route::livewire('articles/{article:id}', 'pages::articles.show')
    ->name('articles.show');

라우팅 설정을 했다.




코드에 대한 자세한 설명은 이 포스트를 참고하자.




위의 포스트에서는 나오지 않는 /{article:id} 구문에 대해서만 설명하겠다.

/{article:id}는 URL에 들어온 숫자로 DB에서 글을 찾으라는 뜻이다.


  • { } (중괄호): URL에서 변하는 값을 받는 곳이다. (/articles/1, /articles/2 등의 숫자가 들어오는 자리)
  • article: 백엔드 코드의 $article 변수와 연결하겠다는 뜻이다.
  • :id: DB의 id 컬럼(글 번호)을 기준으로 검색하라는 뜻이다.


이렇게 하면 사용자가 '/articles/5'로 접속했을 때, 라라벨이 DB에게 "id가 5번인 Article(글)을 찾아서 $article 변수에 넣어줘."라고 자동으로 처리한다.


만약 :id를 생략하고 /{article}이라고만 적어도 라라벨은 기본적으로 id 컬럼을 기준으로 데이터를 찾는다.

하지만 :id를 명시해주면 코드를 읽는 사람에게 '이 라우트는 ID 값을 기준으로 조회한다'는 의도를 명확하게 보여주는 효과가 있다.





글 목록 페이지에 링크 생성


resources/views/pages/articles/⚡list.blade.php

<a href="{{ route('articles.show', $article) }}" wire:navigate class="text-indigo-500 hover:text-indigo-700">
    {{$article->title}}
</a>

글 목록에서 제목을 클릭하면 해당 글의 show(개별글) 페이지로 갈 수 있게 링크를 생성했다.




글 목록 페이지의 글 제목에 링크가 생겼다

글 목록 페이지에 표시된 글 제목이 클릭할 수 있게 됐다.

이제 마지막으로 개별글 페이지가 제대로 표시되도록 show 컴포넌트를 수정해 보자.




개별글 표시하기


resources/views/pages/articles/⚡show/show.php

new class extends Component
{
    public Article $article;

    public function mount(Article $article)
    {
        $this->article = $article->load('user:id,nickname');
    }
};

이젠 백엔드 로직과 뷰 파일이 따로 나뉘게 됐다.


  • public Article $article;: 컴포넌트의 공개 프로퍼티로 모델 객체를 지정했다. 그러면 Blade 템플릿 영역에서 곧바로 $article->title, $article->body 형태로 접근할 수 있다.
  • public function mount(Article $article): 라우트에 설정한 articles/{article:id} 설정 덕분에, 라라벨이 URL로 전달된 id에 해당하는 Article의 DB 레코드를 자동으로 찾아 $article 변수에 채워준다.
  • $article->load('user:id,nickname'): show.blade.php에서 $article->user->nickname을 사용하기 때문에, 뷰가 렌더링 될 때 작성자 정보를 가져오는 쿼리를 최적화하여 실행한다.


이렇게 URL 파라미터로 넘어온 값(ID 등)을 보고, 라라벨이 DB에서 해당 모델 객체를 자동으로 찾아서 주입Binding해 주는 기능을 라우트 모델 바인딩Route Model Binding이라고 한다.





resources/views/pages/articles/⚡show/show.blade.php

<div>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
            {{ __('Articles') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-3 lg:px-4">
            <div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900 dark:text-gray-100">
                    <div class="border rounded-md p-3">
                        <p>제목: {{$article->title}}</p>
                        <p>작성자: {{$article->user->nickname}}</p>
                        <p>{{$article->created_at}}</p>
                        <hr class="my-3">
                        <p>{{$article->body}}</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

미리 언급했듯이 디자인은 거의 신경 쓰지 않은 뷰 파일이다.

일단 데이터를 나열해서 표시만 할 수 있다면 성공이다.




개별글 페이지

여기까지 저장한 후, 글 목록에서 확인할 글의 제목을 클릭하면 이렇게 개별글을 확인할 수 있게 된다.




CRUD 중에서 Create와 Read까지 구현했다.

다음 포스트에서는 글을 수정Update하는 기능을 구현할 차례인 것 같다.

별다른 변수가 없다면 다음 포스트에서는 글 수정 기능을 구현해 보도록 하겠다.




다음 포스트

이 글이 도움이 됐거나 유익했다면 스크롤을 조금만 더 내려서 댓글을 남겨주세요. (비로그인도 가능합니다!)
응원이나 피드백이 담긴 댓글은 제가 계속 블로그를 해나갈 수 있는 원동력이 됩니다. 😊

지인에게 보여주고 싶은 글이었다면 URL을 복사해서 메신저나 소셜 미디어에 공유해 주세요.
이전 포스트 다음 포스트

댓글 쓰기

0 Comments

문의하기 양식