Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Eloquent, le relazioni

Analizziamo il funzionamento delle diverse tipologie di relazione tra i dati nelle tabelle gestite da Eloquent, l'ORM del framework PHP Laravel.
Analizziamo il funzionamento delle diverse tipologie di relazione tra i dati nelle tabelle gestite da Eloquent, l'ORM del framework PHP Laravel.
Link copiato negli appunti

Come tutti gli ORM che si rispettino, anche Eloquent è in grado di gestire le relazioni tra le entità in maniera facile e trasparente per l'utilizzatore. Laravel permette di implementare facilmente 6 tipologie di relazioni:

  • Uno a uno.
  • Uno a molti.
  • Molti a molti.
  • Molti a molti indiretta.
  • Polimorfiche.
  • Polimorfiche molti a molti.

Il modello presente in Eloquent per definire relazioni si basa sulla presenza di particolari metodi all'interno delle nostre classi. Questi metodi offrono una duplice funzionalità: invocando il metodo otterremo un oggetto programmabile (basato sui query builders di Laravel) per effettuare particolari operazioni, come ad esempio i filtri, mentre sfruttando le magic properties di PHP possiamo recuperare il valore della relazione come se fossero property.

$song->artist->name // restituisce 'R.E.M.'
$sont->artist() // restituisce l'oggetto che rappresenta la relazione

Come abbiamo visto nell'articolo precedente, Eloquent offre un sistema di convention over configuration eccellente che, se rispettato, permette di creare strutture di dati complesse praticamente senza scrivere alcuna riga di configurazione. Ovviamente il consiglio è quello di sfruttare al massimo le convenzioni e di sovrascriverle solamente se sono presenti impedimenti esterni non aggirabili.

Relazioni uno a uno

La relazione uno a uno è la tipologia di relazione più semplice e permette di avere un particolare modello collegato univocamente ad un altro modello. Un esempio di questa relazione potrebbe essere quella tra utente e indirizzo.

Per definire tale relazione è sufficiente creare il metodo address nella classe User e invocare il metodo, ereditato da Model, hasOne.

class User extends Model {
    public function address() {
        return $this->hasOne('App\Address');
    }
}

Il metodo hasOne accetta tre parametri di cui solo il primo obbligatorio. Esso rappresenta il nome completo del modello relazionato. Il secondo parametro, opzionale, permette di definire il nome della colonna che rappresenta la foreign key verso l'entità principale. La convenzione definisce di avere una colonna denominata user_id all'interno della tabella addresses che conterrà l'id dell'utente correlato. Il terzo parametro serve nel caso si volesse utilizzare una colonna diversa dall'id per creare la relazione.

Nel caso fosse necessario creare anche la relazione inversa, ovvero la possibilità di recuperare l'utente a partire dall'indirizzo, sarà necessario utilizzare il metodo privato belongsTo riportando sempre il nome del modello associato. Gli eventuali secondo e terzo parametro rispecchiano lo stesso valore semantico del metodo hasOne.

class Address extends Model {
    public function user() {
        return $this->belongsTo('App\User');
    }
}

E' importante ricordarsi queste due semplici regole:

  • il modello "forte" che non presenta, tra le sue colonne, riferimenti al modello "debole" necessita del metodo hasOne
  • il modello "debole" che presenta, tra le sue colonne, il riferimento al modello "forte" necessita del metodo belongsTo

Relazioni uno a molti

Una relazione uno a molti è similare alla precedente ma permette di associare un particolare modello con una lista di altri modelli che possono avere solamente un padre. L'esempio di prima potrebbe ritornare valido, se supponiamo che un utente può avere diversi indirizzi (per esempio di spedizione, di fatturazione, di residenza...).

Per definire questa relazione creiamo il metodo addresses invocando il metodo hasMany.

class User extends Model {
    public function addresses() {
        return $this->hasMany('App\Address');
    }
}

Come per il metodo hasOne, il secondo e il terzo parametro rappresentano rispettivamente il nome della colonna dell'entità debole e la chiave primaria dell'entità forte. Impostando la relazione in questo modo possiamo quindi ottenere la lista degli indirizzi associati ad un particolare utente:

User::find(123)->addresses

Sfruttando invece l'oggetto che rappresenta la relazione è possibile effettuare filtri:

User::find(123)->addresses()->where('city', 'Milano')->get()

Per definire la relazione inversa possiamo utilizzare il metodo belongsTo nello stesso modo analizzato per le relazioni uno a uno.

Nel prossimo capitolo verranno analizzate le restanti tipologie di relazione, più articolate rispetto a quelle già esposte.

Ti consigliamo anche