Livewire로 Chirper 구축 - Chirps 생성 편집하기

경고: 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. 로그인하거나 계정을 생성하면 편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.

편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.

최신판 당신의 편집
32번째 줄: 32번째 줄:


== 라우팅 ==
== 라우팅 ==
컨트롤러에 대한 URL을 생성하기 위해 <code>routes</code> 디렉토리에 라우트를 추가해야 합니다.
Livewire를 사용하고 있기 때문에, Chirp 생성 폼과 기존 Chirp 목록을 표시하기 위해 단일 <codeRoute::get</code> 라우트만 정의하면 됩니다. 또한, 이 라우트를 두 가지 [[Laravel 미들웨어|미들웨어]] 뒤에 배치할 것입니다:
* <code>auth</code> 미들웨어는 로그인한 사용자만 라우트에 접근할 수 있도록 합니다.
* <code>verified</code> 미들웨어는 [[Laravel 이메일 인증|이메일 인증]]을 활성화할 경우 사용됩니다.
{{소스헤더|routes/web.php}}
<syntaxhighlight lang='php' highlight='3,7-10'>
<?php
use App\Http\Controllers\ChirpController;
use Illuminate\Support\Facades\Route;
Route::view('/', 'welcome');
Route::get('chirps', [ChirpController::class, 'index'])
    ->middleware(['auth', 'verified'])
    ->name('chirps');
Route::view('dashboard', 'dashboard')
    ->middleware(['auth', 'verified'])
    ->name('dashboard');
Route::view('profile', 'profile')
    ->middleware(['auth'])
    ->name('profile');
require __DIR__.'/auth.php';
</syntaxhighlight>
{{NOTE}}
애플리케이션의 모든 라우트를 보려면 <code>php artisan route:list</code> 명령어를 실행하면 됩니다.
{{/NOTE}}
새 <code>ChirpController</code> 클래스의 <code>index</code> 메소드에서 테스트 메시지를 반환하여 라우트와 컨트롤러를 테스트해봅시다:
{{소스헤더|app/Http/Controllers/ChirpController.php}}
<syntaxhighlight lang='php' highlight='5,9-15'>
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Response;
class ChirpController extends Controller
{
    /**
    * Display a listing of the resource.
    */
    public function index(): Response
    {
        return response('Hello, World!');
    }
}
</syntaxhighlight>
이전에 로그인된 상태라면 http://localhost:8000/chirps , 또는 Sail을 사용 중이라면 http://localhost/chirps 로 이동하여 메시지를 확인할 수 있습니다.
== Livewire ==
== Livewire ==
아직까진 별 게 없죠? 이제 <code>ChirpController</code> 클래스의 <code>index</code> 메소드를 업데이트하여 Blade 뷰를 렌더링해 봅시다.
== 내비게이션 메뉴 ==
 
{{소스헤더|app/Http/Controllers/ChirpController.php}}
<syntaxhighlight lang='php' highlight='5,12-17'>
<?php
 
namespace App\Http\Controllers;
 
use Illuminate\View\View;
 
class ChirpController extends Controller
{
    /**
    * Display a listing of the resource.
    */
    public function index(): View
    {
        return view('chirps', [
            //
        ]);
    }
}
</syntaxhighlight>
 
이제 Blade 템플릿을 생성하고 새로운 Chirp를 생성할 폼을 렌더링하는 Livewire 컴포넌트를 포함해 봅시다:
 
{{소스헤더|resources/views/chirps.blade.php}}
<syntaxhighlight lang='php'>
<x-app-layout>
    <div class="max-w-2xl mx-auto p-4 sm:p-6 lg:p-8">
        <livewire:chirps.create />
    </div>
</x-app-layout>
</syntaxhighlight>
 
다음으로, 폼을 렌더링할 Livewire 컴포넌트를 생성합시다. 이를 위해, Artisan 명령어인 <code>make:volt</code>를 사용할 수 있습니다.
 
아래의 스니펫은 컴포넌트를 생성하는 두 가지 방법을 제시합니다: 하나는 <code>Class</code>(클래스) API를 사용하는 방법이고, 다른 하나는 <code>Functional</code>(함수형) API를 사용하는 방법입니다. 이 튜토리얼 전반에서 두 API를 모두 보실 수 있으며, 선호하는 스타일의 Livewire 개발 방식을 선택하실 수 있습니다.
 
{{소스헤더|클래스}}
<syntaxhighlight lang='bash'>
php artisan make:volt chirps/create --class
</syntaxhighlight>
 
이 명령어는 새로운 Livewire 컴포넌트를 <code>resources/views/livewire/chirps/create.blade.php</code>에 생성합니다.
 
Livewire 컴포넌트를 업데이트하여 폼을 표시해 봅시다:
 
{{소스헤더|resources/views/livewire/chirps/create.blade.php}}
<syntaxhighlight lang='php' highlight='7,11-20'>
<?php
use Livewire\Volt\Component;
new class extends Component
{
    public string $message = '';
}; ?>
<div>
    <form wire:submit="store">
        <textarea
            wire:model="message"
            placeholder="{{ __('What\'s on your mind?') }}"
            class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
        ></textarea>
        <x-input-error :messages="$errors->get('message')" class="mt-2" />
        <x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button>
    </form>
</div>
</syntaxhighlight>
 
이제 브라우저에서 페이지를 새로고침하여 기본 레이아웃에 렌더링된 새로운 폼을 확인하세요!
 
[[파일:chirp-form.png]]
 
스크린샷이 위와 같지 않다면, Vite 개발 서버를 중지하고 다시 시작하여 Tailwind가 우리가 방금 만든 새 파일의 CSS 클래스를 감지할 수 있도록 해야 할 수 있습니다.
 
이 시점부터는 Vite 개발 서버가 <code>npm run dev</code>로 실행 중일 때 Blade 템플릿에 변경사항을 자동으로 브라우저에서 새로고침합니다.
 
==내비게이션 메뉴==
Breeze에서 제공하는 내비게이션 메뉴에 링크를 추가해봅시다.
 
데스크톱 화면에 대한 메뉴 항목을 추가하려면 Breeze에서 제공하는 <code>navigation.blade.php</code> 컴포넌트를 업데이트하세요:
 
{{소스헤더|resources/views/livewire/layout/navigation.blade.php}}
<syntaxhighlight lang='php' highlight='5-7'>
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
    <x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')" wire:navigate>
        {{ __('Dashboard') }}
    </x-nav-link>
    <x-nav-link :href="route('chirps')" :active="request()->routeIs('chirps')" wire:navigate>
        {{ __('Chirps') }}
    </x-nav-link>
</div>
</syntaxhighlight>
 
모바일 화면에도 추가하려면:
 
{{소스헤더|resources/views/livewire/layout/navigation.blade.php}}
<syntaxhighlight lang='php' highlight='5-7'>
<div class="pt-2 pb-3 space-y-1">
    <x-responsive-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')" wire:navigate>
        {{ __('Dashboard') }}
    </x-responsive-nav-link>
    <x-responsive-nav-link :href="route('chirps')" :active="request()->routeIs('chirps')" wire:navigate>
        {{ __('Chirps') }}
    </x-responsive-nav-link>
</div>
</syntaxhighlight>
 
== Chrip 저장 ==
== Chrip 저장 ==
우리의 폼은 <code>Chirp</code> 버튼을 클릭할 때 <code>store</code> 액션을 호출하도록 설정되어 있습니다. 이제 데이터를 검증하고 새 Chirp를 생성하기 위해 <code>chirp.create</code> 컴포넌트에 <code>store</code> 액션을 추가하겠습니다.
{{소스헤더|resources/views/livewire/chirps/create.blade.php}}
<syntaxhighlight lang='php' highlight='3,8,10-18'>
<?php
use Livewire\Attributes\Validate;
use Livewire\Volt\Component;
new class extends Component
{
    #[Validate('required|string|max:255')]
    public string $message = '';
    public function store(): void
    {
        $validated = $this->validate();
        auth()->user()->chirps()->create($validated);
        $this->message = '';
    }
}; ?>
<div>
    <form wire:submit="store">
        <textarea
            wire:model="message"
            placeholder="{{ __('What\'s on your mind?') }}"
            class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
        ></textarea>
        <x-input-error :messages="$errors->get('message')" class="mt-2" />
        <x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button>
    </form>
</div>
</syntaxhighlight>
Livewire의 <code>Validate</code> 속성을 사용하여 사용자가 데이터베이스 컬럼의 255자 제한을 초과하지 않는 메시지를 제공하도록 하기 위해 Laravel의 강력한 검증 기능을 활용하고 있습니다.
그 후, <code>chirps</code> 관계를 활용하여 로그인된 사용자에 속하는 레코드를 생성하고 있습니다. 이 관계는 곧 정의할 예정입니다.
마지막으로, <code>message</code> 폼 필드 값을 비우고 있습니다.
== 관계 생성 ==
== 관계 생성 ==
이전 단계에서 <code>auth()->user()</code> 객체에 <code>chirps</code> 메소드를 호출한 것을 눈치챘을 것입니다. 이 메소드를 <code>User</code> 모델에 생성하여 [[Eloquent: 관계#일대다|"has many"]] 관계를 정의해야 합니다:
{{소스헤더|app/Models/User.php}}
<syntaxhighlight lang='php' highlight='3,11-14'>
<?php
...
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
...
    public function chirps(): HasMany
    {
        return $this->hasMany(Chirp::class);
    }
}
</syntaxhighlight>
{{NOTE}}
Laravel은 다양한 종류의 모델 관계를 제공하며, 이에 대해서는 [[Eloquent 관계]] 문서에서 더 자세히 읽을 수 있습니다.
{{/NOTE}}
== 대량 할당 보호 ==
== 대량 할당 보호 ==
요청의 모든 데이터를 모델에 전달하는 것은 위험할 수 있습니다. 예를 들어, 사용자가 자신의 프로필을 편집할 수 있는 페이지가 있다고 생각해 보세요. 만약 요청 전체를 모델에 전달한다면, 사용자는 <code>is_admin</code> 컬럼과 같은 어떤 컬럼이든 편집할 수 있게 됩니다. 이것을 [[대량 할당 취약성]]이라고 합니다.
Laravel은 기본적으로 대량 할당을 차단하여 실수로 이러한 일이 발생하는 것을 방지합니다. 그러나 대량 할당은 매우 편리합니다. 왜냐하면 각 속성을 하나씩 할당하는 수고를 덜어주기 때문입니다. 우리는 "fillable" 속성으로 안전한 속성을 표시하여 대량 할당을 활성화할 수 있습니다.
<code>Chirp</code> 모델에 <code>$fillable</code> 속성을 추가하여 <code>message</code> 속성에 대한 대량 할당을 활성화해 봅시다:
{{소스헤더|app/Models/Chirp.php}}
<syntaxhighlight lang='php' highlight='6-8'>
<?php
...
class Chirp extends Model
{
...
    protected $fillable = [
        'message',
    ];
}
</syntaxhighlight>
Laravel의 대량 할당 보호에 대해 더 알고 싶다면 [[Eloquent#대량 할당|문서]]를 참조하십시오.
== 마이그레이션 업데이트 ==
== 마이그레이션 업데이트 ==
애플리케이션을 생성할 때, Laravel은 이미 <code>database/migrations</code> 디렉토리에 포함된 기본 마이그레이션을 적용했습니다. 현재 데이터베이스 구조를 점검하려면 <code>php artisan db:show</code>와 <code>php artisan db:table</code> 명령어를 사용할 수 있습니다:
애플리케이션을 생성할 때, Laravel은 이미 <code>database/migrations</code> 디렉토리에 포함된 기본 마이그레이션을 적용했습니다. 현재 데이터베이스 구조를 점검하려면 <code>php artisan db:show</code>와 <code>php artisan db:table</code> 명령어를 사용할 수 있습니다:

제타위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는 제타위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다. 저작권이 있는 내용을 허가 없이 저장하지 마세요!

취소 편집 도움말 (새 창에서 열림)