laravel超入門講座、今回は、リレーションを実践してみます。
リレーションとは、テーブル間の連携をつくるもの。
今回はテーブルとテーブルを1対1で結ぶhasOneメソッドとbelongsToメソッドを解説します。
記事に書いてあるとおりの手順で実践してみると、リレーションが作れるようになります。
前回までの講座はこちらをどうぞ。
hasOne・belongsToで1対1リレーション構築
hasOneメソッドとbelongsToメソッドは、テーブル間で1対1の関係を構築するときに使います。
たとえば会員情報用のuserテーブルと、各会員の住所を記録したaddressテーブルがあるとします。
このときuserテーブルが主で、ユーザー情報を補足しているaddressテーブルは、userテーブルに対して従属した関係になっています。
ふたつのテーブルをユーザーIDを介して、リレーションを構築します。
hasOneメソッドを使ってリレーションを定義する
まずuserテーブル側からリレーションを作る方法を考えてみましょう。
userテーブルは、addressテーブルのなかにあるユーザーIDを持っていることになります。
userテーブルの側からaddressテーブルにリレーションを作るときは、【hasOne】メソッドを使います。
belongsToメソッドを使ってリレーションを定義する
次に、addressテーブルの側から考えてみましょう。
addressテーブルは、userテーブルのなかのカラムを使っており、userテーブルに属している関係です。
addressテーブルの側からuserテーブルに対してリレーションを作るときは、【belongsTo】メソッドを使います。
hasOneメソッドを使ったリレーションを実践
それではリレーションを実際に作ってみましょう。
最初はhasOneメソッドを解説します。
①アドレスモデルとマイグレーションファイルを作成する
userテーブルは最初からあるものを使います。
addressテーブルのモデルとマイグレーションファイルを新たに作成します。
次のようにコマンドを入力します。
1 |
php artisan make:model Address -m |
②アドレスのマイグレーションファイルを編集する
作成したアドレスのマイグレーションファイルは、database/migrationsの中にあります。
ファイルを開き、user_idカラムとaddressカラムを追加しましょう。
下記の2行を加えます。
1 2 |
$table->foreignId('user_id'); $table->string('address'); |
追加後のマイグレーションファイルは、次のようになります。
保存して、マイグレートを実行します。
1 |
php artisan migrate |
③MySQLにデータを追加しておく
MySQLにログインし、addressテーブルができたことを確認してください。
【挿入】ボタンを押します。
アドレスデータをひとつ追加しておきましょう。user_idには、1を、addressには「東京都ととろ村」と入れておきます。
*もしuserテーブルが空っぽであれば、ユーザーも追加しておきましょう。
もしuserテーブルが空っぽであれば、ユーザーも1人追加しておきます。
④Userモデルにリレーションを追加する
Userモデルを編集して、リレーションを追加します。
app/Models/User.phpファイルを開きます。
最後の波カッコ【 }】の前に、下記を加えてください。
1 2 3 |
public function address(){ return $this->hasOne(Address::class); } |
このモデル(ユーザーモデル)が、アドレスモデル(App\Address)とhasOneの関係にあります。
これだけで、ユーザーモデルからアドレスモデルを呼び出せるようになりました。
すごくシンプルなコードですよね。
ただアドレステーブルの中の【ユーザーID】のカラム名を変えたり、【ユーザーID】以外のカラムと連携させたりする場合は、コードの書き方が少し変わります。
こちらの記事にまとめてあるので、気になる方だけ読んでください。
⑤リレーションを確認してみる
それでは実際にリレーションがどう動作するか見てみます。
routesフォルダの中のweb.phpというルートファイルを開きます。
まずはweb.phpファイルの先頭に、名前空間を省略してUserモデルを呼び出せるよう、 use 文をいれておきます。
1 |
use App\Models\User; |
次に、下記のコードを追加します。
1 2 3 4 |
Route::get('/{id}/address', function($id){ $user=User::find($id); return "ユーザー番号".$id."番の住所:".$user->address->address; }); |
コードの意味
- {id}/address ページにアクセスしたら、function() { } の命令を実行します。
- ユーザーは、$id 番号のユーザーとします。
- 「”ユーザー番号”.$id.”番の住所:”.$user->address->address;」という文を返してください。$user->address->addressは、このユーザーの、addressテーブルの中にある「アドレス」を取ってくるという意味です。
⑥ページを表示してみよう
Laravelのサーバーを起動して、ページを確認してみてください。
ブラウザを開き、デフォルトのページのURLに 【/1/address】と加えます。
ユーザー番号1番のユーザーの住所情報が表示されていれば成功!
belongsToメソッドを使ってリレーションを実践
それでは今まで作ってきたデータを使って、次にbelongsToメソッドを使ってみましょう。
これは、addressテーブルからuserテーブルへリレーションを定義する方法です。
英語の豆知識
belong to は「~に属する」という意味になります。
主となるモデル・テーブルに従属するというイメージですね。
①Addressモデルにリレーションを追加する
appフォルダのAddress.phpファイルを開きます。
最後の波カッコ【 }】の前に、下記を加えてください。
1 2 3 |
public function user(){ return $this->belongsTo(User::class); } |
このモデル(アドレスモデル)は、ユーザーモデル(App\User)に対してbelongsToの関係にあります。
このように設定したことで、アドレスモデルからユーザーモデルを呼び出せるようになりました。
②リレーションを確認してみる
それでは実際にリレーションがどう動作するか見てみます。
routesフォルダの中のweb.phpというルートファイルを開きます。
Addressモデルを名前空間を省略して呼び出せるように、 web.phpファイルの先頭に下記の一文を書き加えてください。
1 |
use App\Models¥Address; |
次に、下記のコードを追加します。
1 2 3 4 |
Route::get('/{id}/address', function($id){ $address=Address::find($id); return "アドレス番号".$id."のユーザーの名前は".$address->user->name."さんです。"; }); |
コードの意味
- {id}/addressページにアクセスしたら、function() { } の命令を実行します。
- アドレス番号は、$id 番のアドレスとします。
- 「”アドレス番号”.$id.”のユーザーの名前は”.$address->user->name.”さんです。”」という文を返してください。$address->user->nameは、このアドレス番号をもつユーザーの「name」を取ってくるという意味です。
③ページを表示してみよう
Laravelのサーバーを起動して、ページを確認してみてください。
ブラウザを開き、デフォルトのページのURLに 【/1/address】と加えます。
アドレス番号1のユーザーの名前が表示されていれば成功!
さいごに
今回のまとめ
- 1対1でテーブルをつなぐ関数にはhasOneメソッドとbelongsToメソッドがある
- 主となる側でリレーションを定義する時はhasOne, 従となる側でリレーションを定義する時はbelongsToを使う
次回もリレーションについて解説していきますね。
最初は難しく感じられるかもしれません。
ただ実際に作ってみたり、シチュエーションを考えてみたりするうちに、理解できるようになっていきます。
本来ならコントローラファイルとビューファイルを使用しますが、いまは実験なのでルートファイルに表示用のコードを記述します。