백엔드/laravel

라라벨에서 일대다 다형 관계 구현하기: 포스트, 비디오, 코멘트 예시

janggos 2024. 1. 27. 15:51

라라벨에서는 일대다 다형 관계를 정의할 수 있습니다.

이는 하나의 모델이 여러 다른 모델과 관련이 있는 관계를 설정하는 데 사용됩니다.

다형 관계는 하나의 모델이 여러 모델과 관련이 있을 때 사용됩니다.

 

세 가지 모델 간의 다형 관계를 구현할 것이며,

포스트(Post) 모델, 비디오(Video) 모델, 그리고 코멘트(Comment) 모델을 사용합니다.

 

비디오(Video) 모델, 그리고 코멘트(Comment) 모델 생성

 

php artisan make:model Video -m;

php artisan make:model Comment -m;

 

database\migrations\2024_01_27_061434_create_videos_table.php

---------------------------------------------------------------------------

public function up(): void
{
    Schema::create('videos', function (Blueprint $table) {
        $table->id();
        $table->string(column: 'title');
        $table->string(column: 'url');
        $table->text(column: 'description');
        $table->timestamps();
    });
}

 

database\migrations\2024_01_27_061457_create_comments_table.php

-------------------------------------------------------------------------------

public function up(): void
{
    Schema::create('comments', function (Blueprint $table) {
        $table->id();
        $table->text(column: 'body');
        $table->unsignedBigInteger(column: 'commentable_id');
        $table->string(column: 'commentable_type');
        $table->timestamps();
    });
}

 

php artisan migrate;

 

모델 간의 관계를 설정

 

app\Models\Comment.php

------------------------------

 

class Comment extends Model
{
    use HasFactory;

    protected $fillable = ['body', 'commentable_id', 'commentable_type'];

    public function commentable(): MorphTo
    {
        return $this->morphTo();
    }
}

 

 

app\Models\Video.php

---------------------------

 

class Video extends Model
{
    public function comments(): MorphMany
    {
        return $this->morphMany(related: Comment::class, name: 'commentable');
    }
}

 

app\Models\Post.php

--------------------------

 

class Post extends Model
{
    public function comments(): MorphMany
    {
        return $this->morphMany(related: comment::class, name: 'commentable');
    }
}

 

 

php artisan Tinker;

---------------------

> $post = Post::find(5);
= App\Models\Post {#5963
    id: 5,
    user_id: 6,
    title: "Enim facere quia eos suscipit.",
    slug: "enim-facere-quia-eos-suscipit",
    excerpt: "Sunt iusto asperiores ab id.",
    description: "Et est omnis fugit beatae hic et.",
    is_published: 0,
    min_to_read: 5,
    created_at: "2024-01-14 01:30:46",
    updated_at: "2024-01-14 01:30:46",
  }

> $comment = $post->comments()->create(['body'=>'This is a new comment.']);
= App\Models\Comment {#5940
    body: "This is a new comment.",     
    commentable_id: 5,
    commentable_type: "App\Models\Post",
    updated_at: "2024-01-27 07:01:35",  
    created_at: "2024-01-27 07:01:35",  
    id: 1,
  }

 

> $comment = $post->comments()->create(['body'=>'This is a new comment 2.']);
= App\Models\Comment {#5960
    body: "This is a new comment 2.",
    commentable_id: 5,
    commentable_type: "App\Models\Post",
    updated_at: "2024-01-27 07:02:50",
    created_at: "2024-01-27 07:02:50",
    id: 2,
  }

 

> $post->comments;
= Illuminate\Database\Eloquent\Collection {#6084
    all: [
      App\Models\Comment {#6086
        id: 1,
        body: "This is a new comment.",
        commentable_id: 5,
        commentable_type: "App\Models\Post",
        created_at: "2024-01-27 07:01:35",
        updated_at: "2024-01-27 07:01:35",
      },
      App\Models\Comment {#6087
        id: 2,
        body: "This is a new comment 2.",
        commentable_id: 5,
        commentable_type: "App\Models\Post",
        created_at: "2024-01-27 07:02:50",
        updated_at: "2024-01-27 07:02:50",
      },
    ],
  }

 

> foreach($post->comments as $comment) {
.    echo $comment->body . '\n';
. }
This is a new comment.\nThis is a new comment 2.\n

 

> Video::create(['title' => '   1', 'url' => 'i dont', 'description' => 'big fun']);
= App\Models\Video {#5986
    title: "외계인1",
    url: "i dont",
    description: "big fun",
    updated_at: "2024-01-27 07:09:14",
    created_at: "2024-01-27 07:09:14",
    id: 1,
  }

 

> $video = Video::find(1);
= App\Models\Video {#5956
    id: 1,
    title: "외계인1",
    url: "i dont",
    description: "big fun",
    created_at: "2024-01-27 07:09:14",
    updated_at: "2024-01-27 07:09:14",
  }

 

> $comment = $video->comments()->create(['body'=> 'This is a new Comment']);
= App\Models\Comment {#5988
    body: "This is a new Comment",
    commentable_id: 1,
    commentable_type: "App\Models\Video",
    updated_at: "2024-01-27 07:13:42",
    created_at: "2024-01-27 07:13:42",
    id: 3,
  }

 

> $video->comments;
= Illuminate\Database\Eloquent\Collection {#5963
    all: [
      App\Models\Comment {#5961
        id: 3,
        body: "This is a new Comment",
        commentable_id: 1,
        commentable_type: "App\Models\Video",
        created_at: "2024-01-27 07:13:42",
        updated_at: "2024-01-27 07:13:42",
      },
    ],
  }

 

> Comment::all();
= Illuminate\Database\Eloquent\Collection {#5951
    all: [
      App\Models\Comment {#5953
        id: 1,
        body: "This is a new comment.",
        commentable_id: 5,
        commentable_type: "App\Models\Post",
        created_at: "2024-01-27 07:01:35",
        updated_at: "2024-01-27 07:01:35",
      },
      App\Models\Comment {#5954
        id: 2,
        body: "This is a new comment 2.",
        commentable_id: 5,
        commentable_type: "App\Models\Post",
        created_at: "2024-01-27 07:02:50",
        updated_at: "2024-01-27 07:02:50",
      },
      App\Models\Comment {#5955
        id: 3,
        body: "This is a new Comment",
        commentable_id: 1,
        commentable_type: "App\Models\Video",
        created_at: "2024-01-27 07:13:42",
        updated_at: "2024-01-27 07:13:42",
      },
    ],
  }