Rumah >pembangunan bahagian belakang >tutorial php >Pengenalan semula hubungan polimorfik yang fasih ' s
mata teras
morphTo
atau morphMany
digunakan untuk model yang berkaitan dengan model lain. morphOne
MorphMap
Laravel menyokong banyak hubungan polimorfik, yang membolehkan model menjadi milik pelbagai model secara banyak. Ini amat berguna dalam aplikasi yang kompleks.
Anda mungkin telah menggunakan pelbagai jenis hubungan antara model atau jadual pangkalan data, seperti biasa di Laravel: satu-satu, satu-ke-banyak, banyak-banyak, dan mempunyai banyak. Tetapi terdapat satu lagi jenis yang kurang biasa: persatuan polimorfik. Jadi apakah persatuan polimorfik?
Persatuan Polymorphic merujuk kepada model yang boleh dimiliki oleh beberapa model lain dalam satu persatuan.
apa yang akan kita binaUntuk menggambarkan ini, mari kita buat adegan fiksyen di mana kita mempunyai topik dan model pos. Pengguna boleh meninggalkan komen dalam topik dan jawatan. Menggunakan hubungan polimorfik, kita boleh menggunakan jadual komen tunggal untuk kedua -dua kes. Menghairankan, bukan? Ini seolah -olah agak tidak praktikal kerana idealnya kita perlu membuat jadual Post_Comments dan jadual Topic_comments untuk membezakan komen. Menggunakan hubungan polimorfik, kami tidak memerlukan dua jadual. Mari memahami hubungan polimorfik melalui contoh praktikal.
kami akan membuat aplikasi muzik demo yang mengandungi lagu dan album. Dalam aplikasi ini, kami boleh menyukai lagu dan album. Menggunakan hubungan polimorfik, kami akan menggunakan jadual Upvotes tunggal untuk kedua -dua kes. Pertama, mari kita periksa struktur jadual yang diperlukan untuk membina hubungan ini:
mari kita bincangkan lajur
dan<code>albums id - integer name - string songs id - integer title - string album_id - integer upvotes id - integer upvoteable_id - integer upvoteable_type - string </code>, yang mungkin kelihatan sedikit pelik kepada mereka yang tidak menggunakan hubungan polimorfi sebelum ini. Lajur
akan mengandungi nilai ID album atau lagu, manakala lajur upvoteable_id
akan mengandungi nama kelas yang memiliki model. Lajur upvoteable_type
adalah bagaimana ORM menentukan "jenis" mana yang akan kembali memiliki model apabila mengakses hubungan upvoteable_id
. upvoteable_type
Saya menganggap anda sudah mempunyai aplikasi Laravel yang sedang berjalan. Jika tidak, kursus permulaan cepat ini boleh membantu. Mari kita mulakan tiga model dan migrasi, dan kemudian mengedit migrasi untuk memenuhi keperluan kita.
<code>albums id - integer name - string songs id - integer title - string album_id - integer upvotes id - integer upvoteable_id - integer upvoteable_type - string </code>
Perhatikan bahawa lulus bendera -m
apabila membuat model juga akan menghasilkan migrasi yang berkaitan dengan model -model ini. Mari kita laraskan kaedah up
dalam migrasi ini untuk mendapatkan struktur meja yang dikehendaki:
{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
Sekarang, kita boleh menjalankan perintah migrasi tukang untuk membuat ketiga -tiga jadual ini:
<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>
mari kita konfigurasikan model kami untuk memberi perhatian kepada hubungan polimorfik antara album, lagu dan suka:
<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
Kaedah
<code class="language-php">[...] class Upvote extends Model { /** * 获取所有拥有模型。 */ public function upvoteable() { return $this->morphTo(); } }</code>mentakrifkan hubungan one-to-banyak polimorfik antara model-model ini dan model upvote dan akan membantu kita mendapatkan semua contoh model tertentu.
app/Song.php
Selepas menentukan hubungan, kita kini boleh mencuba permohonan untuk lebih memahami bagaimana hubungan polimorfik berfungsi. Kami tidak akan membuat sebarang pandangan untuk aplikasi ini, kami hanya akan mencuba aplikasi kami dari konsol.
<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>Jika anda menganggap pengawal dan di mana kita harus meletakkan kaedah seperti itu, saya cadangkan membuat albumupvotecontroller dan songupvotecontroller. Dengan cara ini, apabila kita berurusan dengan hubungan polimorfik, kita boleh menyambungkan perkara dengan ketat ke objek yang kita beroperasi. Dalam kes kami, kami boleh menyukai album dan lagu. Suka bukan album atau lagu. Juga, ia bukan seperti umum, yang bertentangan dengan bagaimana kita mempunyai UpvotesController dalam kebanyakan hubungan satu-ke-banyak. Semoga ini masuk akal.
upvotes
mari kita mulakan konsol:
Hubungan pengambilan semula
Sekarang bahawa kami mempunyai beberapa data siap, kami dapat mengakses hubungan kami melalui model kami. Berikut adalah tangkapan skrin data dalam jadual upvotes:
<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>
juga boleh mengambil pemilik hubungan polimorfik dari model polimorfik dengan mengakses nama kaedah yang melakukan panggilan ke . Dalam kes kita, itu adalah kaedah
upvotes
Hubungan
<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 akan mengembalikan contoh album, kerana ini seperti yang dimiliki oleh contoh contoh album.
Kerana kita boleh mendapatkan bilangan suka untuk lagu atau album, kita boleh menyusun lagu atau album berdasarkan The Likes on the View. Begitulah carta muzik berfungsi.
untuk lagu, kita akan suka seperti ini:
<code>albums id - integer name - string songs id - integer title - string album_id - integer upvotes id - integer upvoteable_id - integer upvoteable_type - string </code>
Secara lalai, Laravel akan menggunakan nama kelas yang berkelayakan sepenuhnya untuk menyimpan jenis model yang berkaitan. Sebagai contoh, dalam contoh di atas, Upvote mungkin tergolong dalam album atau lagu, dan lalai upvoteable_type
adalah App\Album
atau App\Song
masing -masing.
)? Ini bermakna kita perlu menetapkan panjang maksimum yang sangat panjang pada lajur. Di sinilah kaedah App\Models\Data\Topics\Something\SomethingElse
dapat membantu kami. MorphMap
<code>php artisan make:model Album -m php artisan make:model Song -m php artisan make:model Upvote -m </code>kita boleh mendaftarkan morphMap dalam fungsi boot AppServiceProvider, atau membuat pembekal perkhidmatan yang berasingan. Agar perubahan baru berkuat kuasa, kita mesti menjalankan perintah dump-autoload komposer. Jadi sekarang kita boleh menambah rekod seperti ini:
<code class="language-php">public function up() { Schema::create('albums', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); }</code>Ia berkelakuan sama seperti contoh sebelumnya.
Kesimpulan
Saya harap anda kini memahami hubungan polimorfik dan apa yang mungkin diperlukan untuk jenis hubungan ini. Satu lagi contoh hubungan polimorfik yang lebih maju ada di sini. Jika anda mendapati ini membantu, sila kongsi dengan rakan anda dan jangan lupa untuk klik butang seperti itu. Jangan ragu untuk meninggalkan pemikiran anda di bahagian komen di bawah!
Soalan Lazim Mengenai Hubungan Polymorphic Eloquent
Menubuhkan hubungan polimorfik di Laravel melibatkan hubungan yang menentukan dalam model fasih. Pertama, anda perlu menentukan hubungan pada model yang akan menerima hubungan polimorfik. Ini dilakukan menggunakan kaedah morphTo
. Kemudian, pada model yang akan dikaitkan dengan model lain, gunakan kaedah morphMany
atau morphOne
mengikut sama ada hubungan itu adalah satu-ke-banyak atau satu.
Sudah tentu, mari kita pertimbangkan platform blog di mana kedua -dua jawatan dan pengguna boleh mempunyai komen. Dalam kes ini, model komen akan mempunyai hubungan polimorfik dengan model pos dan pengguna. Inilah cara untuk menentukan hubungan ini:
<code>albums id - integer name - string songs id - integer title - string album_id - integer upvotes id - integer upvoteable_id - integer upvoteable_type - string </code>
Anda boleh mendapatkan rekod yang relevan dalam hubungan polimorfik seperti yang anda lakukan dengan hubungan fasih yang lain. Sebagai contoh, jika anda ingin mengambil semua komen dari siaran, anda boleh melakukan ini:
<code>php artisan make:model Album -m php artisan make:model Song -m php artisan make:model Upvote -m </code>
Simpan rekod yang berkaitan dalam hubungan polimorfik juga serupa dengan hubungan fasih yang lain. Anda boleh mengaitkan model menggunakan kaedah associate
dan menyimpan model. Berikut adalah contoh:
<code class="language-php">public function up() { Schema::create('albums', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); }</code>
Hubungan polimorfik amat berguna dalam situasi di mana model boleh tergolong dalam pelbagai jenis model lain. Sesetengah kes penggunaan biasa termasuk komen yang boleh dimiliki oleh jawatan dan pengguna, tag yang boleh digunakan untuk pelbagai jenis kandungan, dan imej atau fail yang boleh dilampirkan kepada pelbagai jenis entiti.
Walaupun hubungan polimorfik memberikan banyak fleksibiliti, mereka juga mungkin lebih kompleks dan lebih sukar untuk ditubuhkan dan dikendalikan daripada hubungan fasih standard. Mereka juga menyokong semua ciri hubungan standard, seperti keinginan untuk memuatkan kekangan.
anda boleh menggunakan kaedah delete
pada hubungan untuk memadam rekod yang relevan dalam hubungan polimorfik. Sebagai contoh, untuk memadam semua komen dari siaran, anda boleh melakukan ini:
<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>
Ya, Laravel menyokong banyak hubungan polimorfik melalui kaedah morphToMany
dan morphedByMany
. Ini membolehkan model menjadi milik pelbagai model secara banyak.
Dalam penghijrahan pangkalan data, anda biasanya menambah dua lajur ke jadual yang akan menerima hubungan polimorfik: satu untuk ID model yang berkaitan dan yang lain untuk jenis model yang berkaitan. Laravel menyediakan kaedah morphs
yang mudah untuk menambah lajur ini:
<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>
Ini menambah commentable_id
dan commentable_type
lajur ke meja.
Atas ialah kandungan terperinci Pengenalan semula hubungan polimorfik yang fasih ' s. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!