今回は、Laravelで1対多のリレーションを作るhasManyメソッドを解説します。
そもそもリレーションって何?と思ったら、まずこちらの記事に目をとおしてくださいね。
リレーションを設定すると、データベースから効率的に値を取得したりできます。
hasManyでリレーション構築
今回ご紹介するhasManyメソッドは、テーブル間で1対多の関係を構築するときに使います。
たとえば、部署データをいれたテーブルと、従業員データをいれたテーブルの間に設定したりできます。
ひとつの部署には複数の従業員が所属していますよね。
部署名を入れたdivisionテーブルと、従業員情報を入れたuserテーブルを作成し、ここでhasManyのリレーションを定義できます。ふたつのテーブルは、division_idを介して連携させることができます。
図にすると、下記のようになります。
【部署テーブルと従業員テーブルの間にリレーションを設定した場合】
hasManyメソッドを使ったリレーションを実践
なんとなくイメージをつかんでいただけたでしょうか?
ここからは、実際にLaravel上でhasManyメソッドでリレーションを作っていきます。
①Divisionモデルとマイグレーションファイルを作成する
Divisionモデルとマイグレーションファイルを新たに作成します。
次のようにコマンドを入力します。
1 |
php artisan make:model Division -m |
②Divisionのマイグレーションファイルを編集する
作成したマイグレーションファイルは、database/migrationsの中にあります。
ファイルを開き、部署名用のカラム name を追加しましょう。
1 |
$table->string('name'); |
追加後のマイグレーションファイルは、次のようになります。
保存して、マイグレートを実行します。データベース上にdivisionsテーブルができます。
1 |
php artisan migrate |
③ userテーブルにdivision_idを追加する
次にuserテーブルにdivision_idのカラムを追加します。
カラム追加用に、次のようにコマンドを入力します。
1 |
php artisan make:migration add_column_division_id_to_users_table --table=users |
database/migrations の中にマイグレーションファイルができています。
funciton up () に次のように入力します。
1 |
$table->unsignedBigInteger('division_id'); |
function down() には、up()に書いた内容を打ち消すとき用のコードを書きます。
1 |
$table->dropColumn('division_id'); |
こうしておけば、ロールバック(取消処理)を行ったときにエラーになりません。
入力後のファイルは次のようになります。
保存して、マイグレートを実行します。データベース上のusersテーブルに、division_idカラムが追加されます。
1 |
php artisan migrate |
④Divisionモデルにリレーションを追加する
Divisionモデルを編集して、リレーションを追加します。
app/ModelsフォルダのDivision.phpファイルを開きます。
最後の波カッコ【 }】の前に、下記を加えてください。
1 2 3 |
public function users(){ return $this->hasMany(User::class); } |
このモデル(ディビジョンモデル)は、ユーザーモデルとhasManyの関係にあります。
これで、DivisionモデルからUserモデルを呼び出せるようになりました。
⑤ データベースにデータを追加しておく
データベース(MySQL)にログインします。
次のようになるよう、divisionsテーブルとusersテーブルにデータをいれておきましょう。
divisionsテーブルのid情報が、userテーブルのdivision_idに紐づいています。
divisionsテーブルのid番号1番に紐づくuserは2名います。
*データベースに値を入力する方法ですが、データベーステーブル上部の【挿入】ボタンを押すと、データをいれる画面になります。
下記は、divisionテーブルのnameにデータをいれるときの画面例です。
⑥ リレーションを確認
それでは実際にリレーションがどう動作するか見てみます。
routesフォルダの中のweb.phpというルートファイルを開きます。
Divisionモデルを名前空間を省略して呼び出せるように、 use 文が書かれているかチェックします。
もしなければ、書き加えてください。
1 |
use App\Division; |
次に、下記のコードを追加します。
1 2 3 4 5 6 |
Route::get('/division', function(){ $division = Division::find(1); foreach($division->users as $user){ echo $user->name.'<br>'; } }); |
コードの意味
- /division ページにアクセスしたら、function() { } の命令を実行します。
- divisionテーブルの id = 1 のレコードを読み出して、$division に代入(保管)します。
- foreach文で、$division に属しているユーザたちを一人ずつ $user に代入して {} 内の処理をします。
⑦ページを表示してみよう
Laravelのサーバーを起動して、ページを確認してみてください。
ブラウザを開き、デフォルトのページのURLに 【/division】と加えます。
division番号が1番のユーザーの名前が表示されていれば成功!
⑧逆のリレーションはbelongsToを使う
なお、users→divisionへ逆のリレーションを貼るには、blongsToメソッドを使います。
Userのモデルファイルに、下記のように入力します。
1 2 3 4 5 |
public function division(){ return $this->belongsTo(Division::class); } |
さいごに
- 1対多でテーブルをつなぐ関数にはhasManyメソッドがある
- 部署名と従業員をつなぐときなどに使える
- 主となる側(部署名)のモデルにhasManyメソッドを入力する
リレーションを使いこなせるようになると、データベースを効率的に作れるようになっていきます。
少し応用編になりますが、リレーションを使って中間テーブルを作る方法を解説した記事もあるので、併せて参考にしてください。
ちなみにリレーション先のカラム名をidではないものにしたりする場合は、コードの書き方が少し変わります。こちらは下記をご覧ください。
本来ならコントローラファイルとビューファイルを使用しますが、いまは実験なのでルートファイルに表示用のコードを記述します。