リレーションについて毎回調べてしまっていることが多いので、内容整理として。
(随時更新)
前提
バージョン:Laravel6
一対多
①一対多とは
一対多のリレーションとは、あるmodelインスタンス一つ(ModelA)に対して複数のmodelインスタンス(ModelB)が紐づく関係のこと。その「紐づき」にあたるものが外部キー。あるModelAインスタンスには複数のModelBインスタンスが紐づくが、あるModelBインスタンスは特定のModelAインスタンスにだけ紐づく。
②migration
//ModelAマイグレーション
public function up()
{
Schema::create('model_a', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
//ModelBマイグレーション
public function up()
{
Schema::create('model_b', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('model_a_id'); // 外部キー
$table->string('name');
$table->timestamps();
// 外部キー制約
$table->foreign('model_a_id')->references('id')->on('model_a')->onDelete('cascade');
});
}
外部キー制約はforeign('外部キー')->references('参照先のカラム')->on('参照テーブル')
と記述する。
onDelete('**')
はデータ削除時の振舞いを指定するもの。
-
cascade
:参照先が削除されると、共に削除される。 -
set null
:参照先が削除されると、外部キーがnullになる。 -
restrict
:参照先が削除されると、エラーを返す。
③model
// このインスタンスに紐づくModelBインスタンス
public function modelBs() {
return $this->hasMany(ModelB::class);
}
// このインスタンスに紐づくインスタンスの数を取得する。
public function loadRelationshipCounts() {
$this->loadCount('modelBs');
}
// このインスタンスに紐づくModelAインスタンス
public function modelA() {
return $this->belongsTo(ModelA::class);
}
多対多
①多対多とは
多対多のリレーションとは、あるmodelインスタンス群(ModelC)に対して複数のmodelインスタンス群(ModelD)が紐づく関係のこと。一対多とは異なり、あるModelCインスタンスが複数のModelDインスタンスと紐づくだけでなく、あるModelDインスタンスが複数のModelCインスタンスと紐づくことができる。
多対多を実現するには中間テーブルを用いる。
②migration
//ModelCマイグレーション
public function up()
{
Schema::create('model_c', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
//ModelDマイグレーション
public function up()
{
Schema::create('model_d', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
//中間テーブルマイグレーション
public function up()
{
Schema::create('relay_c_d', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('model_c_id'); // 外部キー
$table->unsignedBigInteger('model_d_id'); // 外部キー
$table->string('name');
$table->timestamps();
// 外部キー制約
$table->foreign('model_a_id')->references('id')->on('model_c')->onDelete('cascade');
$table->foreign('model_a_id')->references('id')->on('model_d')->onDelete('cascade');
});
}
外部キー制約はforeign('外部キー')->references('参照先のカラム')->on('参照テーブル')
と記述する。
onDelete('**')
はデータ削除時の振舞いを指定するもの。
-
cascade
:参照先が削除されると、共に削除される。 -
set null
:参照先が削除されると、外部キーがnullになる。 -
restrict
:参照先が削除されると、エラーを返す。
③model
// このインスタンスに紐づくModelDインスタンス
public function modelDs() {
return $this->belongsToMany(ModelB::class, 'relay_c_d', 'model_c_id', 'model_d_id')->withTimestamps();
}
// このインスタンスに紐づくインスタンスの数を取得する。
public function loadRelationshipCounts() {
$this->loadCount('modelDs');
}
// このインスタンスに紐づくModelCインスタンス
public function modelCs() {
return $this->belongsToMany(ModelC::class, 'relay_c_d', 'model_d_id', 'model_c_id')->withTimestamps();
}
// このインスタンスに紐づくインスタンスの数を取得する。
public function loadRelationshipCounts() {
$this->loadCount('modelCs');
}