Help us understand the problem. What is going on with this article?

同一テーブル内でのリレーションの書き方

やること

同じテーブル内でのリレーション?なるものを実装したので備忘録

環境

  • Laravel5.8
  • Docker
  • MySQL 8.0

内部リレーションとは

あるテーブルのあるカラムの親となるカラムが同じテーブルに存在する時のこと。
例としてTwitterのようなアプリで女子高生たちが会話していると考えます。

バカ:今からスゴイこと言ってイイ?
  ↪️オタ:いいから早く言え
  ↪️バカ:諦めたらそこで試合終了じゃね?
  ↪️ロボ:すごいと思う。すでに試合終了してるのにそのセリフに感動できるあたり。

↪️はリプだと考えてください。

この情報を管理するためにはusersテーブルとcommentsテーブルが必要です。そこでそれぞれを以下のように設計します。

usersテーブル

id name
1 バカ
2 オタ
3 ロボ

commentsテーブル

id user_id comment parent_id
1 1 今からスゴイこと言ってイイ? null
2 2 いいから早く言え 1
3 1 諦めたらそこで試合終了じゃね? 1
4 3 すごいと思う。すでに試合終了してるのにそのセリフに感動できるあたり。 1

どのコメントにコメントをしたのかを表すのがparent_id です。

リレーションはこんな感じで書きます。

Comment.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $guarded = ['id'];

     public function parentComment()
    {
        return $this->hasOne(Comment::class, 'id', 'parent_id');
    }
}

parentComment()は子カラムの親カラムを探す、というメソッドになっていて、第一引数に参照するモデル(テーブル)、第二引数には外部キー、第三引数には子カラムのリレーションキーを書きます。

これでどのコメントにコメントしたかをリレーションで表現できるようになります!

最後に

以前記事にしたClosureTableをEagerloadしたいときに、もし1つ上の親だけを取ってくるならこの方法で呼び出しできるようになります。
ClosureTableを使って〇〇年のアニメを季節ごとに1テーブルで管理する
今回の場合、EagerLoadするなら

Comment::with('comment.parentComment')->get()

でとることができます!

(with使っても複数リレーションするとクエリが亀になってしまうけど。。。)

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away