ホームページ >バックエンド開発 >PHPチュートリアル >雄弁さの多型関係を再導入します

雄弁さの多型関係を再導入します

Lisa Kudrow
Lisa Kudrowオリジナル
2025-02-09 12:17:13590ブラウズ

Re-Introducing Eloquent's Polymorphic Relationships

コアポイント

  • Laravelの多型協会により、モデルは1つの関連付けの他の複数のモデルに属することができます。これにより、データベース構造が簡素化され、コードの維持が容易になり、より動的で柔軟なデータ関係が可能になります。
  • Laravelでの多型関連のセットアップには、雄弁さモデルの関連付けを定義することが含まれます。
  • メソッドは、多型関連モデルを受信するために使用され、morphToまたはmorphManyメソッドは他のモデルに関連付けられたモデルに使用されます。 morphOne
  • Laravelの
  • メソッドを使用して、各モデルのクラス名の代わりにカスタム名を使用するように雄弁に指示することができます。これは、モデルの名前空間の変更または長すぎる名前空間の場合に役立ちます。 MorphMap
  • Laravelは、多目的な多型の関係をサポートしており、モデルが多目的に複数のモデルに属することを可能にします。これは、複雑なアプリケーションで特に役立ちます。

この記事は、Younes Rafieによって査読されました。 SetePointのコンテンツを完璧にするために、SetePointのすべてのピアレビューアに感謝します!


Laravelで共通するなど、モデルまたはデータベーステーブルの間に異なるタイプの関係を使用している可能性があります。しかし、もう1つの一般的でないタイプがあります:多型関連。では、多型協会とは何ですか? Re-Introducing Eloquent's Polymorphic Relationships

多型協会とは、1つの関連付けの複数の他のモデルに属するモデルを指します。

これを説明するために、トピックと投稿モデルがある架空のシーンを作成しましょう。ユーザーはトピックや投稿にコメントを残すことができます。多型関係を使用して、両方のケースに単一のコメントテーブルを使用できます。驚くべきことに、そうですか?理想的には、post_commentsテーブルとTopic_commentsテーブルを作成してコメントを区別する必要があるため、これは少し非現実的です。多型関係を使用して、2つのテーブルは必要ありません。実用的な例を介して多型の関係を理解し​​ましょう。

何を構築するか

曲とアルバムを含むデモミュージックアプリを作成します。このアプリでは、曲やアルバムが好きです。多型関係を使用して、両方のケースに単一のUPVotesテーブルを使用します。まず、この関係を構築するために必要なテーブル構造を調べましょう。

および

列について説明しましょう。

列にはアルバムまたは曲のID値が含まれ、
<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>
列にはモデルを所有するクラス名が含まれます。

列は、ORMがupvoteable_id関係にアクセスするときにモデルを所有するために戻る「タイプ」を決定する方法です。 upvoteable_type

モデルを生成し、移行

私はあなたがすでにランニングアプリケーションを持っていると仮定します。そうでない場合、この高度なクイックスタートコースが役立つ場合があります。最初に3つのモデルと移行を作成し、次に私たちのニーズに合わせて移行を編集しましょう。

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>

モデルを作成するときに-mフラグを渡すと、これらのモデルに関連する移行が生成されることに注意してください。これらの移行のupメソッドを調整して、目的のテーブル構造を取得しましょう。

{some_timestamp}_create_albums_table.php

<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

{some_timestamp}_create_songs_table.php

<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>

{some_timestamp}_create_upvotes_table.php

<code class="language-php">public function up()
{
    Schema::create('songs', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->integer('album_id')->unsigned()->index();
        $table->timestamps();

        $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
    });
}</code>
ここで、職人移行コマンドを実行してこれらの3つのテーブルを作成できます。

アルバム、歌、いいねの間の多型の関係に注意を払うようにモデルを構成しましょう:
<code class="language-php">public function up()
{
    Schema::create('upvotes', function (Blueprint $table) {
        $table->increments('id');
        $table->morphs('upvoteable'); // 添加无符号整数 upvoteable_id 和字符串 upvoteable_type
        $table->timestamps();
    });
}</code>

app/Upvote.php

<code>php artisan migrate</code>

app/Album.php

<code class="language-php">[...]
class Upvote extends Model
{
    /**
     * 获取所有拥有模型。
     */
    public function upvoteable()
    {
        return $this->morphTo();
    }
}</code>

app/Song.php アルバムと曲のモデルの

メソッドは、これらのモデルとupvoteモデルの間の多型の1対多くの関係を定義し、その特定のモデルのインスタンスのようなすべてを手に入れるのに役立ちます。
<code class="language-php">class Album extends Model
{
    protected $fillable = ['name'];

    public function songs()
    {
        return $this->hasMany(Song::class);
    }

    public function upvotes()
    {
        return $this->morphMany(Upvote::class, 'upvoteable');
    }
}</code>

関係を定義した後、多型の関係がどのように機能するかをよりよく理解するためにアプリケーションを試してみることができます。このアプリのビューは作成されません。コンソールからアプリのみを試してみます。 upvotes

コントローラーと同様の方法を配置する場所を検討する場合は、AblumupVoteControllerとSongUpVoteControllerを作成することをお勧めします。このようにして、多型の関係に対処するとき、私たちは動作しているオブジェクトに厳密に接続することができます。私たちの場合、アルバムと曲が好きです。好きなものはアルバムや曲ではありません。また、それは一般的なものではありません。これは、ほとんどの1対多くの関係でupvotescontrollerを持っている方法の反対です。これが理にかなっていることを願っています。

コンソールを始めましょう:

検索関係

<code class="language-php">class Song extends Model
{
    protected $fillable = ['title', 'album_id'];

    public function album()
    {
        return $this->belongsTo(Album::class);
    }

    public function upvotes()
    {
        return $this->morphMany(Upvote::class, 'upvoteable');
    }
}</code>
データが準備が整ったので、モデルを介して関係にアクセスできます。これは、UPVotesテーブルのデータのスクリーンショットです:

アルバムのようなすべてにアクセスするには、Re-Introducing Eloquent's Polymorphic Relationships dynamic属性を使用できます:

また、upvotesへの呼び出しを実行する方法の名前にアクセスすることにより、多型モデルから多型関係の所有者を取得することもできます。私たちの場合、それはupvoteモデルの

メソッドです。したがって、動的プロパティとしてメソッドにアクセスします。
<code>php artisan tinker
>>> $album = App\Album::create(['name' => 'More Life']);
>>> $song = App\Song::create(['title' => 'Free smoke', 'album_id' => 1]);
>>> $upvote1 = new App\Upvote;
>>> $upvote2 = new App\Upvote;
>>> $upvote3 = new App\Upvote;
>>> $album->upvotes()->save($upvote1);
>>> $song->upvotes()->save($upvote2);
>>> $album->upvotes()->save($upvote3);</code>

upvoteモデルのmorphTo関係は、アルバムインスタンスのインスタンスが所有しているため、アルバムインスタンスを返します。 upvoteable

曲やアルバムの数字の数を得ることができるので、ビューの好きなものに基づいて曲やアルバムを並べ替えることができます。それが音楽チャートの仕組みです。

曲については、このような好きなものを手に入れます:

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>
カスタム多型タイプ

デフォルトでは、Laravelは完全に適格なクラス名を使用して、関連するモデルの種類を保存します。たとえば、上記の例では、upv​​oteはアルバムまたは曲に属し、デフォルト

はそれぞれupvoteable_typeまたはApp\Albumに属している可能性があります。 App\Song

しかし、これには大きな欠点があります。アルバムモデルの名前空間が変更された場合はどうなりますか? UPVotesテーブルのすべての出来事を変更するには、何らかの移行を行う必要があります。これは少し難しいです!名前空間が長い場合(例えば

)。これは、列に非常に長い最大長を設定する必要があることを意味します。これは、App\Models\Data\Topics\Something\SomethingElseメソッドが役立つ場所です。 MorphMap

「Morphmap」メソッドは、クラス名ではなく、各モデルのカスタム名を使用するように雄弁に指示します。

AppServiceProviderのブート関数にMORPHMAPを登録するか、別のサービスプロバイダーを作成できます。新しい変更が有効になるためには、Composer Dump-Autoloadコマンドを実行する必要があります。だから今、私たちはこのようなレコードを追加することができます:
<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

前の例とまったく同じ動作します。
<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>

結論

多型の関係を使用する必要がある状況に遭遇したことがない場合でも、その日は最終的に来るかもしれません。 Laravelを使用することの利点は、この状況を処理するのは非常に簡単であり、モデル関連のトリックを実行して物事を機能させる必要はないことです。 Laravelは、多目的な多型の関係をサポートしています。詳細については、こちらをご覧ください。

あなたが今、あなたが多型の関係と、これらのタイプの関係に何が必要かを理解していることを願っています。多型の関係のもう少しのより高度な例はこちらです。これが役立つと思う場合は、友達と共有して、[いいね]ボタンをクリックすることを忘れないでください。以下のコメントセクションにご意見をお聞かせください!

Eloquentの多型関係についてのFAQ

Laravelで多型関係を使用することの利点は何ですか?

Laravelの多型関係は、異なるモデル間で関連データを処理するための柔軟で効率的な方法を提供します。モデルが1つの関連付けで複数の他のタイプのモデルに属することを可能にします。これは、タイプに関係なく、関連するすべてのデータの単一の一意の識別子リストを持つことができることを意味します。これにより、データベース構造が大幅に簡素化され、コードの維持が容易になります。また、複雑なアプリケーションで特に役立つ、より動的で柔軟なデータ関係が可能になります。

Laravelで多型の関係を設定する方法は?

Laravelでの多型関係のセットアップには、雄弁さモデルの関係を定義することが含まれます。まず、多型の関係を受け取るモデルの関係を定義する必要があります。これは、

メソッドを使用して行われます。次に、他のモデルに関連付けられるモデルでは、関係が1対1であるか1対1かどうかに応じてmorphToまたはmorphManyメソッドを使用します。 morphOne

Laravelで多型の関係の例を提供できますか?

もちろん、投稿とユーザーの両方がコメントを持つことができるブログプラットフォームを考えてみましょう。この場合、コメントモデルは、投稿およびユーザーモデルと多型の関係を持ちます。この関係を定義する方法は次のとおりです

関連レコードを取得するために多型関係を使用する方法は?

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>
他の雄弁な関係と同様に、多型の関係で関連する記録を取得できます。たとえば、投稿からすべてのコメントを取得する場合は、これを行うことができます。

多型関係を使用して関連レコードを保存する方法は?

他の雄弁な関係と同様の多型関係に関連するレコードを保存します。モデルを使用してモデルを関連付けて、モデルを保存できます。例は次のとおりです。
<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

多型関係の一般的なユースケースは何ですか?

associate多型関係は、モデルが他の複数のタイプのモデルに属する可能性がある状況で特に役立ちます。いくつかの一般的なユースケースには、投稿やユーザーに属するコメント、複数のタイプのコンテンツに適用できるタグ、さまざまなタイプのエンティティに添付できる画像またはファイルが含まれます。

<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>
多型関係を使用することの制限または短所は何ですか?

多型の関係は多くの柔軟性を提供しますが、標準的な雄弁な関係よりもセットアップと管理がより複雑で難しい場合があります。また、制約を読みたいという欲求など、標準的な関係のすべての機能もサポートしています。

多型関係で関連するレコードを削除する方法は?

関係の

メソッドを使用して、ポリ型関係で関連するレコードを削除できます。たとえば、投稿からすべてのコメントを削除するには、これを行うことができます。

多対多数の関係を持つ多型関係を使用できますか?

はい、Laravelはおよびメソッドを通じて、多目的な多型の関係をサポートしています。これにより、モデルは多目的に複数のモデルに属することができます。 delete

データベース移行における多型関係にどのように対処するか?
<code class="language-php">public function up()
{
    Schema::create('songs', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->integer('album_id')->unsigned()->index();
        $table->timestamps();

        $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
    });
}</code>

データベースの移行では、通常、ポリ型の関係を受け取る2つの列をテーブルに追加します。1つは関連モデルID用、もう1つは関連モデルタイプです。 Laravelは、これらの列を追加するための便利な

メソッドを提供します:

morphToMany morphedByManyこれにより、

および

列がテーブルに追加されます。

以上が雄弁さの多型関係を再導入しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。