이번 블랙프라이데이에서 livewire 관련 강좌가 많은 코드코스 1년 강좌 포로그램이 50% 할인($120 > $60)이라 구매하였습니다.
가장 익숙한 내용인 댓글(comment) 강좌를 3일간 다 들고 난 뒤 내용 정리를 해둡니다.
늘 아는 내용이라고 생각했지만, 역시 강좌를 듣다가 보니 새로운 내용이 좀 있었네요.
회원 탈퇴시 댓글은 남아 있게 마이그레이션
다형성(morph)도 nullable 하게
$table->foreignId('user_id')->nullable()->constrained()
->nullOnDelete(); # not cascadeOnDelete()
$table->nullableMorphs('commentable');
아니면 회원 탈퇴시 댓글 모두 삭제 처리하려면 모델 이벤트 처리
# User.php
public static function booted()
{
static::deleting(static function (User $user) {
$user->comments()->delete();
});
}
다형성 모델을 통해 댓글(comment) 모델을 저장하고 있는데 특이한 점은
commentable_type: App\Models\Article
commentable_id: 1
원래 이렇게 저장되어 있는데
# AppServiceProvider
public function boot(): void
{
Relation::enforceMorphMap([
'article' => Article::class,
]);
}
}
다형성 모델을 매핑을 이렇게 해두면
commentable_type: article
commentable_id: 1
이렇게 저장됩니다.
데이타베이스 용량도 줄이고 검색 쿼리도 더 빨라 질 것 같습니다. ^^
# CommentItem.php
public function replyComment()
{
$this->authorize('reply', $this->comment);
....
}
# CommentPolicy.php
class CommentPolicy
{
public function reply(User $user, Comment $comment)
{
return is_null($comment->parent_id);
}
}
livewire와 찰떡 궁합인 alpinjs를 이용한 directive(지침?) 처리
datetime 값을 기준으로 작성시간이 계속 변경됨
예: 몇초 전 > 1분 전 > 2분 전 ...
/** app.js */
import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm.js';
import humanDate from './directives/humanDate.js';
Alpine.directive('human-date', humanDate);
/** humanDate.js */
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
import ko from 'dayjs/locale/ko'
dayjs.extend(relativeTime)
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.locale(ko)
dayjs.tz.setDefault('Asia/Seoul')
export default (el) => {
let datetime = el.getAttribute('datetime')
if (!datetime) {
return
}
const setHumanTime = () => {
el.innerText = dayjs().tz().to(dayjs.tz(datetime))
}
setHumanTime()
setInterval(setHumanTime, 30000)
}
# comment-item.blade.php
<div class="text-sm"
x-human-date
datetime="{{ $comment->created_at->toDateTimeString() }}">
{{ $comment->created_at->diffForHumans() }}
</div>
원래 제 스타일은 삭제가 발생하면 페이지 전체를 refresh를 했었습니다만, 여기는 그냥 해당 댓글을 감춰버리는 방식을 사용하네요.
# CommentItem
<?php
namespace App\Livewire;
use App\Livewire\Forms\CreateComment;
use App\Livewire\Forms\EditComment;
use App\Models\Comment;
use Livewire\Component;
class CommentItem extends Component
{
public Comment $comment;
public bool $deleted = false;
....
public function deleteComment()
{
...
$this->deleted = true;
}
}
# comment-item.blade.php
<div>
@if (! $deleted)
<div ...>
@endif
</div>
다음은 Build a Multi-room Realtime Chat with Livewire and Reverb (Reverb + livwire 채팅방 구현)을 들어볼 예정입니다.