LoginSignup
3
5

More than 3 years have passed since last update.

【Laravel基礎】複数のテーブルの結びつけ【リレーション】

Last updated at Posted at 2020-11-18

概要

Laravel学習で自分がつまずいた部分を備忘録としてまとめています。
今回は複数のテーブルの結びつけに関する記事です。

この記事でわかる事

テーブルの結合方法(リレーション)
①テーブルの主従関係
②テーブルの設定
③モデルの設定

以下、記事内容です!

テーブルの主従関係

今回はPostテーブルとCommentsテーブルを用意して、結合します。

こうした複数テーブルの結合をリレーションと呼びます。
そして、リレーションにおいて重要なのが主従関係です。
一方のテーブルが主テーブル・もう一方が従テーブルとなり、
この主従関係によって書くコードが変わってきます。

今回の場合だと、Post(記事)に対してComments(コメント)がつくので、
Postテーブルが主、Commentsテーブルが従という関係になります。
ブログのイメージですね。記事がまず先にあって、それに対してコメントがつく。
Twitterだと、まずユーザーがいて、そこから投稿が生まれる。
それが無いと成り立たない側のテーブルが主テーブルになります。

従テーブルは主テーブルのIDを保管するフィールドを用意する必要があります。
このフィールドを外部キーと呼びます。

これを踏まえて、テーブルを設定していきます。

テーブルの設定

今回はPostテーブルとCommentsテーブルを用意しました。
■Postテーブル

posts_table.php
   public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

まずは主テーブルになるPostsテーブル。
こちらは通常通りですね。ID,title,body,投稿日時を設定しました。

■Commentsテーブル

comments_table.php
     public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id')          
         ①$table->integer('post_id'); 
            $table->string('body');
            $table->timestamps();
          ②$table->foreign('post_id')
                  ->references('id')
                  ->on('posts')
                  ->onDelete('cascade');
        });
    }

従テーブルになるCommentsテーブルですが、
従テーブルでは下記2つの設定をする必要があります。

①外部キーの作成
主テーブルのIDを保管するためのフィールドを作成しておきます。
今回はPostテーブルのidを保管するので、'post_id'フィールドとします。

②外部キーの参照先を設定
記事が消された際、紐づくコメントも消されるように設定しないといけません。
ここでは外部キーの参照先を指定し、参照先のデータが消えたら、このテーブルのデータも一緒に消えるよう指示しています。
各コードの内容は下記のような感じですね。
// foreign(フィールド) = このフィールドは下記を参照します
// references(フィールド) = 参照先のフィールド
// on(テーブル名)      = 参照先のテーブル
// onDelete('cascade'); = 上記が削除されたら該当データも一緒に削除

以上がテーブルの設定です。

モデル

次に、モデルの更新です。
まずは主テーブルとなるPostモデルを更新します。
■Postモデル(主)

Post.php
    class Post extends Model
{
    protected $fillable = ['title', 'body'];

    // ①Commentモデルとの紐付け
    public function comments() {
        return $this->hasMany('App\Comment');
    }
}

①commentテーブルとリンクさせるためのcomments関数を作成します。
主テーブルでは、
$this -> hasMany(参照先モデル)とする事で
従テーブルのデータを引っ張ることが可能になります。

■Commentモデル(従)
次にCommentモデルを更新します。

Comment.php
    class Comment extends Model
{
    //
    protected $fillable = ['body'];

    // ②Postモデルへの紐付け
    public function post() {
    return $this->belongsTo('App\Post');
    }

}

②Postテーブルとリンクさせるためのpost関数を作成します。
従テーブルでは、
$this -> belingsTo(参照先モデル)とする事で
従テーブルのデータを引っ張ることが可能になります。

belongToは所属すると言う意味なので、主テーブルに従ずると言う感じですね。

リレーションの確認

ここまでで、テーブルが結合できたかターミナルで確認します。
まずはPostテーブル→Commentsテーブルの確認。
ここでは(①) App\Post::find(2)->comments;によって、
PostテーブルのID:2のデータを呼び出し、
紐づくCommentsテーブルのデータを呼び出しています。

ターミナル

>>>
(①) App\Post::find(2)->comments;

       App\Comment {#3962
         id: "3",
         post_id: "2",
         body: "test",
         created_at: "2020-11-18 17:48:51",
         updated_at: "2020-11-18 17:48:51",
       },
     ],
   }
>>> 

こうですね。紐づくコメントの中身が出てきたのでOKです。

次にCommentsテーブル→Postテーブルへのリレーションを確認します。

ターミナル
>>> App\Comment::find(3)->post;
=> App\Post {#3963
     id: "2",
     title: "title 2",
     body: "body 2",
     created_at: "2020-11-18 17:55:50",
     updated_at: "2020-11-18 17:55:50",
   }
>>> 

こちらも出てきたのでOKです。

まとめ

以上、Laravelにおけるテーブルのリレーションでした。
初めは、hasMany( )とbelongTo( )の違いがよくわからなかったのですが、
主従関係と言う概念を理解すると、違いが腹落ちしました。

最後まで読んで頂きありがとうございました!

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5