PHP/Laravel

【Laravel】1対多のテーブルリレーション・hasMany/belongsToとは?

Laravel-hasMany-belongsTo

Laravelでテーブルのリレーションを定義するhasManyとbelongsToの理解に時間がかかったので、整理がてらまとめてみました。

この記事は、テーブル・レコード・カラム・SQLの基本は理解しているけど、テーブルリレーションって何?hasMany?belongsTo?…という人向けに書いています

1対多(1対N)のリレーションとは?

「著者」と「本」の関係を例に見ていきましょう。

小説家・東野圭吾さんは、たくさんの本を書いています。

  • 白夜行
  • 容疑者Xの献身
  • マスカレードホテル
  • 夢幻花
    ・・・他多数

「1人の小説家が、多数の本を書いている」

これが「1対多」の関係です。

テーブルとサンプルデータを作成してみました。

  • 著者の情報を格納するテーブル:authors
  • 本のタイトルを格納するテーブル:books

各テーブルのカラムとレコードを下記のように作ります。

Laravel-hasMany-belongsTo6

テーブルとモデルのマッピング

モデルとは、テーブルの内容を定義したクラスです。各テーブルに紐づけて、テーブル操作を簡単におこなうことができます。

テーブルのカラム(フィールド)を、プロパティとして持たせているので、テーブルをインスタントして扱うことができます。

SQLをゴリゴリ書かなくても、レコードの抽出・挿入・更新・削除が簡単にできるのです。

1つのテーブルにつき、1つのモデルが紐づきます。Laravelにはテーブルとモデルを紐づける命名規則があります。

Laravelでは、テーブルとモデルを自動でマッピングするための命名規則があります。

モデル名=単数形・テーブル名=複数形にすると、自動でマッピングされます。

この命名規則を破ったネーミングにする場合、特別な記述をするとマッピングできます。(当記事ではふれません)

たとえば、「people」という名前でテーブルを作成した場合、それに紐づけるモデル名は「Person」です。Personはpeopleの単数形ですからね!(むずかしい!)

Laravelの命名規則に従い、テーブルとモデル名はこのとおり作成します。

  • authorsテーブル ⇔ Authorモデル
  • booksテーブル ⇔ Bookモデル
Laravel-hasMany-belongsTo5-2

 

リレーション元・リレーション先

テーブルにリレーションがある場合、リレーション元(主)・リレーション先(従)という考え方をします。

  • リレーション元テーブル=authorsテーブル
  • リレーション先テーブル=booksテーブル

 

これもLaravelの命名規則があります。

  1. リレーションモデルのidカラム
  2. リレーションモデルの、[リレーションモデル名_id]カラム
Laravel-hasMany-belongsTo5

上記の図にあてはめると、2つのテーブルはこのような関係になっています。

Laravel-hasMany-belongsTo7

リレーションを定義するメソッド

【1対多】のリレーションを定義するメソッドがあります。

  • hasManyメソッド…【1対多】のリレーションを定義する
    →【1】側で定義する(Authorモデル)
  • belongsToメソッド…【1対多】の逆向きのリレーションを定義する
    →【多】側で定義する(Bookモデル)
う~ん、なんかいまいちピンとこないなぁ~
もりさん
もりさん
まずは英語の復習からいくよ~!

hasManyのイメージ

“has”は、~を持っているという意味の動詞”have”の三人称単数形です。

もりさん
もりさん
ポイントは単数形だよ!
Laravel-hasMany-belongsTo1

池井戸潤さんも、本をたくさん書いていますね。

Laravel-hasMany-belongsTo2

belongsToのイメージ

【1対多】の関係を、【多】である「本」の立場から見てみましょう。

「本」は、かならず、ひとりの著者に所属します。

たとえば、『白夜行』というタイトルの本は、「東野圭吾」さんの本です。

Laravel-hasMany-belongsTo3

『七つの会議』というタイトルの本は、「池井戸潤」さんの本です。

Laravel-hasMany-belongsTo4

これが【1対多】の「逆向きのリレーション」の考え方です。

モデルの作成

下記のコマンドでAuthorモデルとBookモデルを作成します。

app配下に、Author.phpとBook.phpが作成されます。

Authorモデル(hasMany結合)

hasManyメソッドを使用して、Bookモデルと【1対多】のリレーションを定義します。

 

Bookモデル(belongsTo結合)

belongsToメソッドを使用して、Authorモデルと【1対多】の逆向きのリレーションを定義します。

 

これで、AuthorモデルとBookモデルに「リレーション」ができました。

リレーションを使用したレコード取得

動作確認用にテーブルにデータを作成します。

 

tinkerを起動して名前空間を定義します。

booksテーブル:id(7)の本の著者を取得する

booksテーブルのid=7は『七つの会議』です。『七つの会議』の著者は「池井戸潤」です。

想定どおり「池井戸潤」が取得できました。

もりさん
もりさん
コードの解説いくよ~
Laravel-hasMany-belongsTo8-0

①Book::find(7)

Bookモデルはbooksテーブルに紐づいています。Bookモデルを通して、booksテーブルのid=7のレコードを取得します。

Laravel-hasMany-belongsTo8-1

②Book::find(7)->author

Bookモデルに定義したauthorメソッドを呼び出します。

【1対多】の逆向きリレーション(belongsTo)で、authorsテーブルのレコードが取得できます。
※「authorsテーブルのid」と「booksテーブルのauthor_id」が紐づいていましたね

Laravel-hasMany-belongsTo8-2

③Book::find(7)->author->name

Authorモデルのnameプロパティを取得します。これは、authorsテーブルのnameカラムです。

Laravel-hasMany-belongsTo8-3

これが、リレーションを使用した値の取得方法です。

authorsテーブル:id(1)の著者の本の一覧を取得する

authorsテーブルのid=1は「東野圭吾」です。著者が「東野圭吾」の本をすべて取得します。

 

コードをみていきましょう。

Laravel-hasMany-belongsTo9-0

①Author::find(1)

Authorモデルはauthorsテーブルと紐づいています。Authorモデルを通して、authorsテーブルのid=1のレコードを取得します。

Laravel-hasMany-belongsTo9-1

②Author::find(1)->books

Authorモデルに定義したbooksメソッドを呼び出します。Authorに紐づくすべてのbookを取得します。

Laravel-hasMany-belongsTo9-2

このように、テーブルリレーションを定義することで、テーブルのCRUD操作が簡単にできるのです。

Laravelオススメ本

もりさん
もりさん
私はこの2冊で勉強してるよ~
非エンジニアもプログラミングを学習する時代!

「プログラミング」ってエンジニアとかプログラマーの人がするものでしょ?文系の私には関係ないや~って思っていませんか?

いまは、非エンジニアもプログラミングを学習する時代です!

「プログラミングの必修化」をご存知ですか?

  • 2020年~ 小学校で開始
  • 2021年~ 中学校で開始
  • 2022年~ 高等学校で開始
  • 2024年~ 高校受験科目に新設

学校での必修化に向けて、すでに子ども向けプログラミングスクールが多数開校されています。

あと数年もすれば、あたりまえにプログラミングができる新入社員がやってくる時代になります。

プログラミングってなに?どんなもの?まずは無料体験から試してみませんか?

 

1週間の無料体験あり!
オンラインスクール実績No.1!

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です