Relazioni Polimorfiche con Laravel Eloquent, come definirle e esempi
Le relazioni polimorfiche sono un tipo di relazione tra entità di dato, che consente di associare un modello di dato a più modelli di dato su una singola associazione.
Ciò è particolarmente utile quando una tabella contiene collegamenti a più tabelle.
Vediamo come gestire le relazioni polimorfiche con Eloquent di Laravel.
Tempo di lettura stimato: 5 minuti
Problema
Nella progettazione e gestione dei database, a volte incontriamo situazioni al di fuori delle solite convenzioni dei database relazionali. Ad esempio, quando dobbiamo associare una singola tabella con più tabelle, possiamo incontrare delle relazioni polimorfiche. In questo articolo approfondiremo il concetto di relazione polimorfica, come implementarla elegantemente e in particolare come Eloquent di Laravel ci aiuta semplificandone lo sviluppo.
Scenario di Esempio
Supponiamo di dover implementare un sistema di gestione dei contenuti, comunemente detto Content Management System. Questa sistema deve gestire i commenti per vari tipi di contenuti: articoli , video e immagini . Ciascuno di questi tipi di contenuto viene archiviato nella rispettiva tabella nel database, ci troveremo quindi ad affrontare la seguente problematica:
Tabelle di “commento” ridondanti
Senza relazioni polimorfiche, probabilmente ricorreresti alla creazione di tabelle separate per i commenti associati a ciascun tipo di contenuto. Ciò comporterebbe una proliferazione di tabelle come article_comments, video_comments e image_comments.
Gestire e mantenere queste tabelle potrebbe diventare complicato, man mano che il CMS si popola. Per non parlare della complessità delle query e del codice.
Per risolvere questo problema, possiamo avere due potenziali soluzioni:
- o ripetere in ciascuna delle tabelle l'attributo condiviso più volte. Il che sarà un incubo ogni volta che dovremmo aggiungere dei commenti;
- Oppure creiamo una super tabella chiamata Comments in cui memorizzare tutti gli attributi correlati e quindi creare sottotabelle per ciascun tipo.
Come le relazioni polimorfiche risolvono il problema
Fondamentalmente, una relazione polimorfica consente di associare una singola tabella a più tabelle. Ciò garantisce flessibilità e consente di evitare la creazione di tabelle separate per ogni tipo di associazione. È invece possibile utilizzare una singola tabella per gestire le associazioni in modo dinamico.
Tornando all'esempio del CMS: con una relazione polimorfica, possiamo creare una tabella di commenti collegabile ad articoli, video e immagini, dipende dal contenuto commentato. Quindi le relazioni polimorfiche ci consentono di eliminare le tabelle ridondanti.
Vediamo ora quali sono gli strumenti che Eloquent ci mette a disposizione per implementare le relazioni polimorfiche.
Come funzionano le relazioni polimorfiche
Il polimorfismo consente a una tabella di associarsi a più tabelle utilizzando due attributi specifici, il tipo e l'identificativo: type e id.
Questi campi vengono utilizzati per archiviare le informazioni necessarie per identificare il tipo di record associato e l'identificatore univoco (solitamente la chiave primaria). Nell'esempio che andremo ad approfondire:
- commentable_type: memorizza il tipo del modello associato ("Articolo" o "Video");
- commentable_id contiene il suo ID corrispondente.
La letture dei dati dalle associazioni polimorfiche implica in genere l'uso di JOIN. Nel nostro caso la JOIN unisce la tabella comments con la corrispondente tabella dei contenuti in base a commentable_type e commentable_id . Ciò consente di accedere in modo efficiente ai dati su diversi modelli.
La query SQL che ci consente di recuperare i commenti e gli articoli associati:
SELECT c.*, a.title AS article_title
FROM comments c
JOIN articles a ON c.commentable_type = 'Article' AND c.commentable_id = a.id;
La query seguente per leggere i commenti associati ai video:
SELECT c.*, v.title AS video_title
FROM comments c
JOIN videos v ON c.commentable_type = 'Video' AND c.commentable_id = v.id;
Implementazione con Laravel Eloquent
In Laravel, Eloquent mette a disposizione strumenti ideali per lavorare con relazioni polimorfiche. Ecco una guida passo passo per implementarli:
Torniamo al modello Comment che può essere associato a vari tipi di contenuto come Article, Video e Image.
Andiamo a vedere passo passo la configurazione della associazione polimorfica:
Creazione migration delle tabelle
Innanzitutto, abbiamo bisogno dei file di migrazione per creare le tabelle del database necessarie. Ecco come creare le migration per le tre tabelle:
php artisan make:migration create_articles_table
php artisan make:migration create_videos_table
php artisan make:migration create_comments_table
Il file migration per la tabella comments deve avere i campi definiti come segue
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');
$table->timestamps();
});
}
Dopo aver creato le tabelle con il seguente comando:
php artisan migrate
Andiamo a creare i modelli Comment, Article, Video e Image
php artisan make:model Article
php artisan make:model Video
php artisan make:model Image
php artisan make:model Comment
class Comment extends Model
{
use HasFactory;
public function commentable(){
return $this->morphTo();
}
}
Il metodo morphTo() viene utilizzato nel modello che verrà associato agli altri modelli in modo polimorfico. Consente di recuperare il modello associato senza specificare esplicitamente il tipo esatto. Semplifica il processo di lavoro con le relazioni polimorfiche.
class Article extends Model
{
use HasFactory;
public function comments(){
return $this->morphMany(Comment::class, 'commentable');
}
}
Di seguito il model Article
class Article extends Model
{
use HasFactory;
public function comments(){
return $this->morphMany(Comment::class, 'commentable');
}
}
Di seguito il model Video
class Video extends Model
{
use HasFactory;
public function comments(){
return $this->morphMany(Comment::class, 'commentable');
}
}
Di seguito il model Image
class Image extends Model
{
use HasFactory;
public function comments(){
return $this->morphMany(Comment::class, 'commentable');
}
}
Il metodo morphMany() viene utilizzato per definire una relazione polimorfica uno-a-molti su un modello. Ti consente di recuperare più record associati da vari modelli in modo pulito ed efficiente. Viene spesso utilizzato quando un modello può essere collegato a diversi tipi di modelli correlati.
Letture Correlate
- Relazione molti a molti in un modello dati con Laravel Eloquent ORM
- Cos'è Laravel Eloquent, come si usa, tutorial con esempi
- Come gestire la relazione uno a uno in un modello dati con Laravel Eloquent ORM
- Relazione uno a molti in un modello dati con Laravel Eloquent ORM
- Come creare un report di progetto con Microsoft Project
Ercole Palmeri
Ercole Palmeri
#laravel #php #software #softwaredesign #softwaredevelopment #SoftwareEngineering #Tutorial
https://bloginnovazione.it/relazioni-polimorfiche/47425/
Commenti
Posta un commento