はじめに
テーブルは自身で独立していることよりも他のテーブルを関係を持っていることが多い。
そのため、テーブル同士でリレーションを設定することで他のテーブルへのデータのアクセスが
可能となる。
今回は以下の4ケースについて紹介する。
- 1対1
- 1対多
- 1対多(Inverse)
- 多対多
1対1
まずは1対1で、例として公式ドキュメント同様に、userモデルとphoneモデルを挙げる。
ユーザー1人に対して、携帯電話が1台持っており、1台の携帯電話に対してユーザーは
1人なので1対1のリレーションを持っている。
まずは親モデル(userモデル)にhasOneメソッドを記載する。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function phone()
{
return $this->hasOne('App\Phone'); //第一引数にモデル名
}
}
また、外部キーは自動で「親モデル_id」と指定されてしまうので、他のカラム名に変更したい場合は
第二引数を指定して、オーバーライドしてあげる。
主キーについても、「id」となっているので、第三引数で指定する。
public function phone()
{
return $this->hasOne('App\Phone', 'hoge', 'hogehoge');
}
リレーションが定義できたらEloquentの動的プロパティを使い、phoneモデルのレコードを取得できる。
$phone = User::find(1)->phone;
また、動的プロパティだけではなく、リレーションメソッドを返すことも可能である。
HasOne オブジェクトなどの Eloquent リレーションオブジェクトはクエリビルダとしても動作するので
便利。
$phone = User::find(1)->phone()->where('name', 'Iphone');
逆の関係
PhoneモデルからUserモデルへアクセスするためのリレーションを定義していく。今度は、belongsToメソッドを使っていく。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
public function user()
{
return $this->belongsTo('App\User'); //第一引数にモデル名
}
}
hasOneメソッド同様に、外部キーは自動で「親モデル_id」と指定されてしまうので、他のカラム名に
変更したい場合は第二引数を指定し、主キーについても、「id」となっているので、第三引数で指定する。
1対多
続いて、1対多のケース。アマゾンなどのショッピングサイトのように一つの商品(productモデル)に対して、
複数のレビュー(reviewモデル)があるような状態である。
まずは親モデル(productモデル)から子モデル(reviewモデル)へのリレーションを定義する。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function reviews()
{
return $this->hasMany('App\Review');
}
}
引数については1対1の時と同様である。必要であればオーバーライドする。
リレーション先へのアクセス方法も動的プロパティ、クエリビルダそれぞれで
アクセス可能である。
逆の関係
1対多の逆の関係、子モデル(reviewモデル)から親モデル(productモデル)へのリレーションを定義する際は、
1対1の時と同様にbelongsToメソッドを用いる。引数の考え方も同様。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
public function product()
{
return $this->belongsTo('App\Product');
}
}
多対多
多対多の例として、ユーザー(user)と趣味(hoby)をあげる。
1人のユーザに対して、趣味はスポーツ、映画、料理など複数ある。
また、その逆で、1つの趣味、例えばスポーツが趣味の人は複数人いる
場合が、この多対多の関係にあたる。
また、多対多の場合は、リレーションを定義する2つのテーブル意外に、その両方をつなぐ
中間テーブルを作成する必要がある、
以下、作成テーブル例である。
users
id | name |
---|---|
1 | nobita |
2 | suneo |
3 | sizuka |
4 | doraemon |
5 | takeshi |
hobies
id | category |
---|---|
1 | sports |
2 | cooking |
3 | movie |
4 | reading |
5 | shopping |
hoby_user(アルファベット順にする)
user_id | hoby_id |
---|---|
1 | 2 |
2 | 1 |
3 | 3 |
3 | 5 |
まずは、usersテーブルからhobiesテーブルへアクセスするためにリレーションを定義していく。
belongsToManyメソッドを用いる。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function hobies()
{
return $this->belongsToMany('App\Hoby', 'hoby_user', 'user_id', 'hoby_id');
}
}
- 第一引数: クラス名
- 第二引数: 結合テーブル名(中間テーブル)
- 第三引数: リレーションを定義しているモデルの外部キー名
- 第四引数: 結合するモデルの外部キー名
逆の関係
逆の関係も同様にbelongsToManyメソッドを用いる。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Hoby extends Model
{
public function users()
{
return $this->belongsToMany('App\User');
}
}
終わりに
今回はリレーションを定義する上で、基本的な4パターンを紹介しました。以下、3パターンについては
まだ習得できていないので、またの機会とさせていただきます。
中間テーブルについても、もう少し詳しくかければいいと思います。
- Has Many Through
- ポリモーフィックリレーション
- ポリモーフィック関係の多対多
参考サイト
https://readouble.com/laravel/5.5/ja/eloquent-relationships.html#many-to-many