LaravelEloquentで1対多の関係を構築する方法
このシリーズの前提条件として設定したデモLandingLaravel アプリケーションには、リンクを格納するための単一のデータベーステーブルが含まれています。 このチュートリアルでは、この初期データベース構造を変更して、リンクをリストに編成するために使用する2番目のテーブルを含めます。
このシリーズで使用するリンクとリストの例では、各リンクは1つのリストの一部にすぎませんが、各リストには複数のリンクを含めることができます。 この種の関係は、1対多関係とも呼ばれます。
1対多の関係は、タイプ A と呼ばれる1つのアイテムを、タイプ B の複数のアイテムにリンクできる場合に発生しますが、その逆は当てはまりません。 :タイプ B のアイテムは、タイプAのoneアイテムにのみリンクできます。 このシナリオを現在のデモアプリケーションモデルに置き換えると、 Aはlist
タイプであり、Bはlink
タイプです。
LinkList
モデルの作成
開始するには、リンクのリストを表すモデルとデータベーステーブルを作成する必要があります。 次に、既存の Link モデルとテーブルを更新して、両方のモデル間の関係を含めます。 List
という用語はPHP内部用に予約されているため、その用語で新しいモデルに名前を付けることはできません。 代わりに、この新しいモデルをLinkList
と呼ぶことができます。
まず、アプリケーションディレクトリにいることを確認します。
- cd ~/landing-laravel
artisan
を使用して新しいモデルを作成します。
- docker-compose exec app php artisan make:model LinkList
これにより、app/Model
ディレクトリに新しいモデルクラスが生成されます。
app/Model/LinkList.php
既存のLinkListCLIコマンドの名前を変更する
app/Console/Commands
ディレクトリを見ると、LinkList.php
という名前のクラスファイルがすでに存在することがわかります。 これは、作成したばかりのEloquentモデルと混同しないでください。 このクラスには、artisan
を介してデータベース内のすべてのリンクを一覧表示するCLIコマンドが含まれています。
将来の混乱を避けるために、今がそのクラスとそのコマンドシグネチャの名前を別の名前に変更する良い機会です。 この場合、クラス名LinkShow
を使用します。これは、その名前がクラスの機能も説明しているためです。 app/Console/Commands/LinkList.php
ファイルの名前を別の有効な名前に変更するには、ターミナルで次のコマンドを実行します。
- mv app/Console/Commands/LinkList.php app/Console/Commands/LinkShow.php
次に、コードエディタでファイルapp/Console/Commands/LinkShow.php
を開き、クラス名をLinkList
からLinkShow
に変更し、コマンドシグネチャをlink:list
からlink:show
、次のコードリストで強調表示されている行のように。 終了すると、ファイルは次のようになります。
<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
class LinkShow extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'link:show';
/**
* The console command description.
*
* @var string
*/
protected $description = 'List links saved in the database';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$headers = [ 'id', 'url', 'description' ];
$links = Link::all(['id', 'url', 'description'])->toArray();
$this->table($headers, $links);
return 0;
}
}
完了したら、ファイルを保存して閉じます。 すべてが期待どおりに機能したことを確認するには、新しく名前を変更したlink:show
職人コマンドを実行します。
- docker-compose exec app php artisan link:show
次のような出力が表示されます。
Output+----+-------------------------------------------------+----------------------------------+
| id | url | description |
+----+-------------------------------------------------+----------------------------------+
| 1 | https://digitalocean.com/community | DigitalOcean Community |
| 2 | https://digitalocean.com/community/tags/laravel | Laravel Tutorias at DigitalOcean |
| 3 | https://digitalocean.com/community/tags/php | PHP Tutorials at DigitalOcean |
+----+-------------------------------------------------+----------------------------------+
LinkListモデルの移行の作成
以前のartisan make:model
コマンドで生成した新しいapp/Model/LinkList.php
クラスには、新しいEloquentクラスのジェネリックコードが含まれています。 Doctrineなどの他のORMとは異なり、Eloquentはデータベース構造を変更せず、データ自体のみを処理します。 Eloquentモデルは通常リーンであり、クラスプロパティはモデルのテーブル構造から自動的に推測されます。
Eloquentでデータのみを処理するこのアプローチは、LinkList
クラスのプロパティを設定する必要がないことを意味します。これは、そのモデルのデータベーステーブル構造から推測されるためです。
構造データベースの操作は通常、データベース移行を介してLaravelで処理されます。 移行により、開発者は、テーブルの作成、変更、削除など、データベースの構造上の変更をプログラムで定義できます。
次に、新しい移行を作成して、データベースにlistsテーブルを設定します。
Laravelにデフォルトで含まれているartisan
コマンドラインツールには、コントローラー、モデル、移行などの新しいコンポーネントをブートストラップするためのいくつかのヘルパーメソッドが含まれています。 artisan
を使用して新しい移行を作成するには、次のコマンドを実行します。
- docker-compose exec app php artisan make:migration create_link_lists_table
Output Created Migration: 2021_07_07_152554_create_link_lists_table
このコマンドは、Laravelアプリケーションのdatabase/migrations
ディレクトリの下に、現在の日時に基づいて自動生成された名前と移行名を使用して、新しいファイルを生成します。 このファイルには、listsテーブルを設定するために変更する汎用コードが含まれています。
コードエディタを使用して、生成された移行ファイルを開きます。 現在、ファイルは次のようになっています。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateLinkListsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('link_lists', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('link_lists');
}
}
移行は、artisan migrate
コマンドで実行されると、up()
メソッドを実行します。 これがテーブル定義の目的であり、デフォルトでは、id
主キーフィールドと、created_at
とupdated_at
)が作成されます。 X172X]スキーマメソッド。 これらのフィールドは、モデルが作成および更新されるときに、それぞれEloquentによって自動的に入力されます。 down()
メソッドは、移行がartisan rollback
コマンドでロールバックされるときに呼び出され、通常、コードを実行してテーブルを削除するか、構造の変更を元に戻します。
up
メソッドを変更して、次のフィールドを含めます。
title
:このリストのタイトルを表す文字列description
:リストの説明を表す文字列slug
:タイトルに基づく一意の短い文字列で、通常はユーザーフレンドリーなURLを作成するために使用されます
1対多の関係では、 many 側(このシナリオではlinks テーブルに対応)は、列参照(または外部キー)を保持する側です。その他の要素(リストテーブルに対応)。 つまり、リンク