Laravel リレーション 調べてみた

リレーションとは

DBのテーブルは構築のやり方によっては、各テーブルに関係性がある場合があります。

例えば、ラジオ番組名テーブルとパーソナリティテーブルをリレーションで紐づけてデータを取得する場合などです。

このような場合は、一見すると同テーブルとしてまとめてしまった方がよいように思えるかもしれませんが、データベースの正規化を考慮するとテーブルを分けて実装するのが正しい実装方法になります。

そのため、リレーション はデータベース設計をするにあたって大切な機能になります。

 

Laravelにおけるリレーション

もちろんLaravelにもリレーションを実装する機能が搭載されています、

Laravelのリレーションはeloquentモデルにリレーションの関係を実装します。

 

1対1

1対1の関係は、1つのカラムが別のテーブルの1つのカラムのみと紐づく場合の関係です。

例えば、ラジオ局テーブルと住所テーブルなどは1つのラジオ局に対して1つの住所が紐づくので1対1の関係と言えます。

では、実際に実装方法を紹介していきます。

その前に、主テーブルと従テーブルについて説明します。

主テーブルとはリレーションにおいて、データを別テーブルから紐付けるテーブルのことです。

従テーブルとはその逆で、データを別テーブルからのリレーションによって紐づかれるテーブルのことになります。

主テーブルや従テーブルはDB設計によって変わってくるので一概には言えませんが、上記の例ではラジオ局テーブルが主テーブル、住所テーブルが従テーブルになるケースが一般的かもしれません。

では実際にコードを見ていきます。

今回は、上記の例を用いて、ラジオ局テーブルのeloquentモデルであるRadioStation.phpと住所テーブルのeloquentモデルであるAddress.phpを編集していきます。

RadioStation.php

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class RadioStation extends Model
{
 use HasFactory;

 public function address() ・・・①
 {
   $this->hasOne('\App\Models\Address', 'radioStation_id', 'id');  ・・・②
 }
}

①リレーションは関数として定義します。

②1対1の主→従の関係はhasoneメソッドを用いることで定義できます。第一引数に従テーブル、第二引数に外部キー、第三引数に内部キーを指定します。

なお、第二引数、第三引数は省略可能で、省略した場合は外部キーに「モデル名_id」内部キーに「id」が使用されます。

Address.php

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Address extends Model
{
 use HasFactory;
 
 public function radioStation()
 {
   $this->belongsTo('\App\Models\RadioStation', 'radioStation_id', 'id'); ・・・①
 }
}

①1対1の従→主の関係はbelongsToメソッドを用いることで定義できます。第一引数に主テーブル、第二引数に内部キー、第三引数に外部キーを指定します。

第二引数、第三引数は省略可能で、省略した場合は外部キーに「モデル名_id」内部キーに「id」が使用されます。

 

1対多

1対多の関係は、1つのカラムに対して複数のカラムが紐づいている場合のリレーションになります。

例えば、ラジオ番組テーブルとコーナーテーブルが1対多の関係になります。

1つのラジオ番組に対して、複数のコーナーが紐づいている状態になります。

この場合、主テーブルは1の方、つまりラジオ番組テーブル、従テーブルは多の方、つまりコーナーテーブルになります。

では、実際のコードを見ていきます。

Program.php

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Program extends Model
{
 use HasFactory;

 public function corner()
 {
   $this->hasMany('\App\Models\Corner', 'program_id', 'id'); ・・・①
 }
}

①1対多の主→従の関係では、hasManyメソッドを使用します。第一引数に従テーブル、第二引数に参照先テーブルの外部キー、第三引数に参照元テーブルの内部キーを指定します。

第二・第三引数は、hasOneメソッドと同様のルールで省略が可能です。

Corner.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Corner extends Model
{
 use HasFactory;
 
 public function program()
 {
   $this->belongsTo('\App\Models\Program', 'program_id', 'id'); ・・・①
 }
}

①1対多の従→主のリレーションは、1対1で使用したbelongToメソッドを使用します。

使い方も1対1と全く同じなのでそちらをご参照ください。

 

多対多

多対多とは、複数のカラムに対して複数のカラムが紐づいているリレーションになります。

例えば、ラジオ番組テーブルとリスナーメールテーブルなどです。

リスナーは複数のラジオ番組にメールを送るし、ラジオ番組も複数のリスナーからメールを受け取ります。

この関係の場合、互いのテーブル同士では直接関係を表すのが複雑になってしまうため、中間テーブルというテーブルを新しくDB上に用意します。

中間テーブルには、プライマリキーと各テーブルのIdを一般的に保存します。中間テーブルによって、2つのテーブルのリレーション関係を保存しているという仕組みです。

 

中間テーブル名は、一般的に各テーブル名をアルファベット順に並べた「テーブル名_テーブル名」で作成されます。

もちろん、任意の名前を設定することもできますが、その場合は明示的に中間テーブルを指定する必要があります。

ではコードを見ていきたいと思います。

Program.php

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Program extends Model
{
 use HasFactory;

 public function listenerMail()
 {
   $this->belongsToMany('\App\Models\ListenerMail', 'listerMail_program','program_id', 'listenerMail_id'); ・・・①
 }
}

①多対多を定義するには、belongsToManyメソッドを使用します。

第一引数に関連づけたいeloquentモデル、第二引数に中間テーブル名、第三引数に自分に向けられた外部テーブル、第四引数に相手に向けられた外部テーブルを定義します。

第二引数以降は、省略可能です。

Program.php

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ListenerMail extends Model
{
 use HasFactory;

 public function program()
 {
   $this->belongsToMany('\App\Models\Program', 'listerMail_program','listenerMail_id', 'program_id'); ・・・①
 }
}

基本的に多対多のリレーションではどちらのeloquentモデルにもbelongsToManyメソッドで定義します。

 

以上!!!!!!!