このシリーズの前提条件として設定したデモLandingLaravel アプリケーションには、リンクを格納するための単一のデータベーステーブルが含まれています。 このチュートリアルでは、この初期データベース構造を変更して、リンクをリストに編成するために使用する2番目のテーブルを含めます。

このシリーズで使用するリンクとリストの例では、各リンクは1つのリストの一部ですが、各リストには複数のリンクを含めることができます。 この種の関係は、1対多関係とも呼ばれます。

1対多の関係は、タイプ A と呼ばれる1つのアイテムを、タイプ B の複数のアイテムにリンクできる場合に発生しますが、その逆は当てはまりません。 :タイプ B のアイテムは、タイプAoneアイテムにのみリンクできます。 このシナリオを現在のデモアプリケーションモデルに置き換えると、Alist タイプ、Blink タイプ。

開始するには、リンクのリストを表すモデルとデータベーステーブルを作成する必要があります。 次に、既存の Link モデルとテーブルを更新して、両方のモデル間の関係を含めます。 用語 List PHP内部用に予約されているため、その用語で新しいモデルに名前を付けることはできません。 この新しいモデルと呼ぶことができます LinkList 代わりは。

まず、アプリケーションディレクトリにいることを確認します。

  1. cd ~/landing-laravel

を使用して新しいモデルを作成します artisan:

  1. docker-compose exec app php artisan make:model LinkList

これにより、で新しいモデルクラスが生成されます app/Model ディレクトリ:

app/Model/LinkList.php

あなたがあなたを見れば app/Console/Commands ディレクトリ、あなたはすでにという名前のクラスファイルがあることに気付くでしょう LinkList.php. これは、作成したばかりのEloquentモデルと混同しないでください。 このクラスには、を介してデータベース内のすべてのリンクを一覧表示するCLIコマンドが含まれています。 artisan.

将来の混乱を避けるために、今がそのクラスとそのコマンドシグネチャの名前を別の名前に変更する良い機会です。 この場合、クラス名を使用します LinkShow その名前はクラスが何をするかも説明しているからです。 名前を変更するには app/Console/Commands/LinkList.php ファイルを別の有効な名前にするには、ターミナルで次のコマンドを実行します。

  1. mv app/Console/Commands/LinkList.php app/Console/Commands/LinkShow.php

次に、ファイルを開きます app/Console/Commands/LinkShow.php コードエディタでクラス名をから変更するには LinkListLinkShow、およびからのコマンド署名 link:listlink:show、次のコードリストで強調表示されている行のように。 終了すると、ファイルは次のようになります。

app / Console / Commands / LinkShow.php
<?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 職人のコマンド:

  1. 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 | +----+-------------------------------------------------+----------------------------------+

新しい app/Model/LinkList.php 前に生成したクラス artisan make:model コマンドには、新しいEloquentクラスの汎用コードが含まれています。 Doctrineなどの他のORMとは異なり、Eloquentはデータベース構造を変更せず、データ自体のみを処理します。 Eloquentモデルは通常リーンであり、クラスプロパティはモデルのテーブル構造から自動的に推測されます。

Eloquentでのみデータを処理するこのアプローチは、 LinkList クラスは、そのモデルのデータベーステーブル構造から推測されるためです。

構造データベースの操作は通常、データベース移行を介してLaravelで処理されます。 移行により、開発者は、テーブルの作成、変更、削除など、データベースの構造上の変更をプログラムで定義できます。

次に、新しい移行を作成して、データベースにlistsテーブルを設定します。

The artisan Laravelにデフォルトで含まれているコマンドラインツールには、コントローラー、モデル、移行などの新しいコンポーネントをブートストラップするためのいくつかのヘルパーメソッドが含まれています。 を使用して新しい移行を作成するには artisan、 走る:

  1. docker-compose exec app php artisan make:migration create_link_lists_table
Output
Created Migration: 2021_07_07_152554_create_link_lists_table

このコマンドは、下に新しいファイルを生成します database/migrations 現在の日時に基づいて自動生成された名前と移行名を使用して、Laravelアプリケーションのディレクトリ。 このファイルには、listsテーブルを設定するために変更する汎用コードが含まれています。

コードエディタを使用して、生成された移行ファイルを開きます。 現在、ファイルは次のようになっています。

database / migrations / 2021_07_07_152554_create_link_lists_table.php
<?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');
    }
}

移行は、 up() で実行されたときのメソッド artisan migrate 指図。 これはあなたのテーブル定義が行くところです、そしてそれはデフォルトでそれを作成します id 主キーフィールドと2つのタイムスタンプフィールド(created_atupdated_at)、で定義 timestamps() スキーマメソッド。 これらのフィールドは、モデルが作成および更新されるときに、それぞれEloquentによって自動的に入力されます。 The down() 移行がロールバックされたときにメソッドが呼び出されます artisan rollback コマンドを実行し、通常はコードを実行してテーブルを削除するか、構造上の変更を元に戻します。

変更します up 次のフィールドを含める方法:

  • title:このリストのタイトルを表す文字列
  • description:リストの説明を表す文字列
  • slug:タイトルに基づく一意の短い文字列。通常、ユーザーフレンドリーなURLを作成するために使用されます

1対多の関係では、 many 側(このシナリオではlinks テーブルに対応)は、列参照(または外部キー)を保持する側です。その他の要素(リストテーブルに対応)。 つまり、リンクテーブルをリストテーブルにリンクする参照フィールドを含めるには、後でリンクテーブルを変更する必要があります。

一方、 lists テーブルには、リンクを参照するための特別なフィールドは必要ありません。

移行ファイルの現在のコンテンツを次のコードに置き換えます。

database / migrations / 2021_07_07_152554_create_link_lists_table.php
<?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();
            $table->string('title', 60);
            $table->string('slug', 60)->unique();
            $table->text('description')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('link_lists');
    }
}

完了したらファイルを保存します。

次に、コードエディタで既存のリンク移行ファイルを開きます。 デモプロジェクトでは、次のパスで移行を見つけることができます。

2020_11_18_165241_create_links_table.php

まず、 use の完全修飾クラス名を指すディレクティブ LinkList クラス、ファイルの先頭と最後の直後 use ライン:

use Illuminate\Support\Facades\Schema;
use App\Models\LinkList;
...

次に、テーブル定義に次の行を含めます。 up メソッドとを設定する行の直後 description 分野:

$table->text('description');
$table->foreignIdFor(LinkList::class);

The foreignIdFor() メソッドは、参照されるEloquentモデルへの外部キー列を作成します。 デフォルトの命名法を使用して、参照されるテーブルの主キーフィールドにリンクされているフィールドを設定します。

完了したら、完全な移行クラスは次のようになります。

database / migrations / 2020_11_18_165241_create_links_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\LinkList;

class CreateLinksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('links', function (Blueprint $table) {
            $table->id();
            $table->string('url', 200);
            $table->text('description');
            $table->foreignIdFor(LinkList::class);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('links');
    }
}

編集が終了したら、ファイルを保存します。 次に、データベースをワイプしてから、移行コマンドを再度実行して、更新された移行ファイルを使用してデータベース構造を再作成します。

  1. docker-compose exec app php artisan db:wipe
  2. docker-compose exec app php artisan migrate

Eloquentモデル関係の構成

これでデータベーステーブルが設定されましたが、それらの間の関係を定義するためにEloquentモデルを構成する必要があります。

List 関係のone側であるモデル、という名前の新しいメソッドを設定します links. このメソッドは、プロキシとして機能し、各リストに関連するリンクにアクセスします。 hasMany 親からのメソッド Illuminate\Database\Eloquent\Model クラス。

コードエディタで、ファイルを開きます app/Model/LinkList.php. 現在の汎用コードを次のコンテンツに置き換えます。

app / Model / LinkList.php
<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
 
class LinkList extends Model
{
    use HasFactory;
 
    public function links()
    {
        return $this->hasMany(Link::class);
    }
}
 

完了したらファイルを保存します。

次に、リレーションシップの many 側を編集して、 List リンクがそれぞれのリストにアクセスできるようにモデル化します。 これは、 belongsTo 親からのメソッド Model クラス。 この方法は、1対多の関係の逆辺を定義するために使用されます。

を開きます Link コードエディタのモデル:

app/Model/Link.php

の現在のコンテンツを置き換えます Link.php 次のコードでファイルします。

app / Model / Link.php
<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Link extends Model
{
    public function link_list()
    {
        return $this->belongsTo(LinkList::class);
    }
}
 

完了したらファイルを保存します。

両方のモデルが更新されると、データベースは完全に構成されますが、現在は空です。 このシリーズの次のセクションでは、Eloquentモデルを使用してデータベースに新しいレコードを挿入する方法を学習します。