본문으로 건너뛰기

DB와 모델 관계

Laravel에서는 DB 테이블을 직접 SQL로만 다루지 않고, Model을 통해 객체처럼 다룹니다.

zenoBlog의 핵심 모델은 네 개입니다.

모델테이블역할
Postposts블로그 글
Categorycategories글 분류
Tagtags글 태그
Userusers로그인 사용자

posts 테이블

posts 테이블은 블로그 글을 저장합니다.

컬럼의미
id글 고유 번호
title글 제목
slugURL용 글 식별자
content본문 HTML
excerpt목록용 요약
thumbnail대표 이미지 경로
meta_titleSEO 제목
meta_descriptionSEO 설명
is_published공개 여부
published_at발행일
category_id연결된 카테고리 id
created_at, updated_at생성/수정 시간

Post 모델

protected $fillable = [
'title',
'slug',
'content',
'excerpt',
'thumbnail',
'meta_title',
'meta_description',
'is_published',
'published_at',
'category_id',
];

fillable은 대량 할당이 가능한 컬럼 목록입니다.

컨트롤러에서 Post::create([...])를 쓸 때, 여기에 없는 컬럼은 저장되지 않습니다.
보안상 아무 컬럼이나 외부 입력으로 저장되지 않게 막는 장치입니다.

casts

protected $casts = [
'is_published' => 'boolean',
'published_at' => 'datetime',
];

DB에는 is_published가 0/1로 저장될 수 있지만, PHP에서는 true/false로 다루게 해줍니다.

published_at은 문자열이 아니라 날짜 객체처럼 다룰 수 있습니다.

$post->published_at->format('Y.m.d')

Category 관계

글 하나는 카테고리 하나에 속합니다.

public function category()
{
return $this->belongsTo(Category::class);
}

이 관계 덕분에 Blade에서 이렇게 쓸 수 있습니다.

{{ $post->category->name }}

반대로 카테고리 하나는 여러 글을 가질 수 있습니다.

public function posts()
{
return $this->hasMany(Post::class);
}

관계 그림은 이렇습니다.

Category 1개
-> Post 여러 개

Tag 관계

글과 태그는 다대다 관계입니다.

글 A -> Laravel, PHP
글 B -> Laravel, 배포

한 글에는 태그가 여러 개 붙을 수 있고, 한 태그도 여러 글에 붙을 수 있습니다.

그래서 post_tag 중간 테이블이 필요합니다.

posts
-> post_tag
-> tags

Post 모델:

public function tags()
{
return $this->belongsToMany(Tag::class);
}

Tag 모델:

public function posts()
{
return $this->belongsToMany(Post::class);
}

post_tag 테이블

컬럼의미
post_id글 id
tag_id태그 id

마이그레이션에는 중복 방지 코드가 있습니다.

$table->unique(['post_id', 'tag_id']);

같은 글에 같은 태그가 두 번 붙지 않도록 막습니다.

users 테이블과 관리자

Laravel Breeze의 기본 users 테이블에 is_admin 컬럼이 추가되어 있습니다.

$table->boolean('is_admin')->default(false)->after('email');

User 모델에는 관리자 여부를 확인하는 메서드가 있습니다.

public function isAdmin(): bool
{
return $this->is_admin === true;
}

관리자 미들웨어는 이 메서드를 사용해서 /admin 접근을 허용하거나 막습니다.