
Che cos’è Eloquent ORM
Eloquent ORM arriva insieme al framework Laravel per lavorare con un database in modo semplice e senza complicazioni. Tra le funzionalità che ne hanno fatto la fama ci sono il soft delete, i timestamp, l’implementazione di ActiveRecord, la gestione di più database, l’eager loading, gli observer dei modelli, gli eventi dei modelli e molto altro. Le relazioni Eloquent sono metodi delle classi dei modelli Eloquent. Definite come metodi, le relazioni diventano potenti query builder: puoi concatenare le chiamate e costruire query molto espressive.
Come funziona Eloquent ORM
Eloquent ORM è noto per la sua implementazione di Active Record. Active Record è un pattern architetturale in cui ogni modello dell’architettura MVC corrisponde a una tabella del database. Con Eloquent crei facilmente le relazioni fra i dati e lavori con un modello a oggetti. Scrivere query SQL a mano è lungo e noioso, Laravel Eloquent ti lascia eseguire le operazioni più comuni senza query SQL interminabili. I modelli rendono banali inserimento, aggiornamento, eliminazione e sincronizzazione su più database. Ti basta definire le tabelle e le relazioni fra di esse.
Iniziare con Eloquent
Laravel include un’interfaccia a riga di comando integrata, la Artisan Console. Si appoggia al componente Console di Symfony e rende comodo l’uso del terminale durante lo sviluppo dell’applicazione.
Prima di andare avanti, configura la connessione al database nel file config/database.php.
Prima di usare i modelli Eloquent, verifica di avere Laravel installato. Se non lo hai, puoi scaricarlo da getcomposer.org
Per vedere l’elenco dei comandi disponibili in Artisan, digita:
php artisan listSullo schermo compaiono tutti i comandi con una breve descrizione. Se ti serve aiuto su uno di essi, digita il comando preceduto da « help ». Per esempio:
php artisan help migrateCreare i modelli Eloquent
Prima di ogni altra cosa devi creare un modello. È il modello a dialogare con il database: ti serve per interrogarlo e per popolarlo con i seeder. Di solito i modelli si mettono in App\Models, per una questione di ordine: l’unico vincolo reale è che siano caricati automaticamente in base al file composer.json. Tutti i modelli Eloquent estendono la classe Illuminate\Database\Eloquent\Model. Il comando di base per creare un modello è make:model di Artisan:
php artisan make: model StudentLa sintassi di base per definire un modello è:
class User extends Model {}Puoi generare anche la migration insieme al modello, aggiungendo -m o -migration al comando precedente.
php artisan make:model Student--migration
php artisan make:model Flight -mSeeder, factory, controller e altri tipi di classi si generano passando i parametri giusti al comando make:model di Artisan. Qualche esempio:
php artisan make:model Flight --factory
php artisan make:model Flight -f
php artisan make:model Flight --seed
php artisan make:model Flight -s
php artisan make:model Flight --controller
php artisan make:model Flight -cQuesti parametri si possono anche combinare per creare più classi in una sola volta.
php artisan make:model Flight -mfscAlcune convenzioni dei modelli da tenere a mente:
- Nome della tabella: per convenzione si usa il plurale del nome del modello. Se il modello si chiama Student, la tabella si chiamerà students. Se il nome del modello contiene più parole, separale con un trattino basso.
- Chiave primaria: Eloquent presume che la chiave primaria sia l’attributo id. Puoi comunque cambiarla con la proprietà $primaryKey.
- Timestamp: per impostazione predefinita created_at e updated_at sono gestiti automaticamente da Eloquent. Se non li vuoi automatici, imposta $timestamp a false. Per personalizzare il formato di data e ora, usa la proprietà $dateFormat del modello.
Aggiornare ed eliminare i modelli
Aggiornare
Per aggiornare un modello lo recuperi, modifichi l’attributo che ti interessa e chiami il metodo save. Il campo updated_at viene aggiornato da solo: non devi toccarlo a mano.
$student = Student::find(1);
$student->email = ‘xyz@example.com';
$student>save();L’aggiornamento di massa è possibile anche su tutti i modelli che corrispondono a una query.
Eliminare un modello esistente
Per eliminare un modello basta chiamare il metodo delete:
$student = Student::find(1);
$student>delete();Eliminazione per chiave:
Student::destroy(1);
Student::destroy([1, 2, 3]);
Student::destroy(1, 2, 3);Puoi anche eliminare in base a una query.
$affectedRows = Student::where('votes', '>', 100)->delete();Modelli correlati
In un database ci sono spesso modelli correlati: due o più modelli che dipendono l’uno dall’altro. Per esempio, se vuoi aggiungere un commento a un post, invece di valorizzare a mano post_id puoi salvarlo direttamente a partire dal modello padre.
$comment = new Comment(['message' => 'A new comment.']);
$post = Post::find(1);
$comment = $post->comments()->save($comment);Associare i modelli
Questi modelli si aggiornano anche con il metodo associate, che imposta la chiave esterna sul modello. Puoi associare anche modelli con relazioni multiple.
Eventi del modello
Ogni volta che il ciclo di vita di un modello passa da una fase, salvataggio, aggiornamento, eliminazione, viene lanciato un evento del modello. Gli eventi disponibili sono saving, saved, updating, updated, deleting, deleted, restoring e restored. Per esempio, quando inserisci un record nuovo parte creating/created, se il record esiste già, parte updating/updated.
Annullare il salvataggio a partire da un evento
Se l’evento restituisce false, l’operazione viene annullata. Vale per qualunque evento: deleting, updating, creating, saving.
Student::creating(function($student)
{
if ( ! $student>isValid()) return false;
});Registrare i listener degli eventi
Come in qualsiasi linguaggio, un evento va registrato da un service provider. Qui il posto giusto è EventServiceProvider, che ospita i binding degli eventi dei modelli.
Per esempio:
public function boot(DispatcherContract $events)
{
parent::boot($events);
Student::creating(function($student)
{
//
});
}Gli observer dei modelli
Gli observer aiutano a organizzare la gestione degli eventi dei modelli. Una classe observer può avere un metodo per ciascun evento del modello.
class StudentObserver {
public function saving($model)
{
//
}
public function saved($model)
{
//
}
}Un altro modo di registrare un observer è il metodo observe.
User::observe(new UserObserver);Generare gli URL dei modelli
Passando un modello ai metodi route o action ottieni l’URL corrispondente: la sua chiave primaria viene inserita nell’URI.
Route::get('student/{student}', 'StudentController@show');
action('StudentController@show', [$student]);Qui nell’URL finisce l’id dello studente. Se vuoi usare un’altra proprietà nell’URL generato, ridefinisci il metodo getRouteKey nel modello.
public function getRouteKey()
{
return $this->slug;
}Altre funzionalità di Laravel Eloquent
Convertire in array o in JSON
Quando costruisci un’API il risultato è quasi sempre JSON, quindi devi convertire i modelli e le loro relazioni in array o in JSON. Anche qui Laravel Eloquent ti copre: per convertire in array un modello e le sue relazioni c’è il metodo toArray().
$student = Student::with('roles')->first();
return $student->toArray();Per convertire un’intera collection di modelli in array, i metodi sono questi:
return Student::find(1)->toJson();Vediamo ora come restituire un modello da una rotta. Ogni volta che un modello viene convertito in stringa diventa JSON: puoi quindi restituire gli oggetti Eloquent direttamente dalle rotte.
Route::get('student', function()
{
return Student::all();
});Alcuni campi sensibili, come personal_id o la password, devono restare nascosti. Per farlo, aggiungi la proprietà $hidden al modello.
Cast degli attributi
Per convertire il tipo di dato di un attributo puoi scrivere un mutator per ciascuno, il che richiede tempo e apre la porta ai bug. L’altra strada è il cast: aggiungi l’attributo alla proprietà casts del modello. Gli altri tipi accettati sono integer, float, double, real, object, string, array.
Ecco un esempio.
protected $casts = [
'is_student' => 'boolean',
];In questo esempio is_student è memorizzato con un altro tipo di dato, ma quando lo leggi ti viene restituito come booleano.
Il cast in array è molto utile quando lavori con una colonna che contiene JSON serializzato, cioè un oggetto codificato in una stringa. Se una colonna contiene JSON serializzato, il cast array la trasforma automaticamente in un array PHP quando la leggi dal modello Eloquent.
protected $casts = [
'options' => 'array',
];Mutator delle date
Carbon è un’estensione PHP di DateTime usata in tutto il mondo. Eloquent converte created_at e updated_at in istanze Carbon, che estendono la classe DateTime di PHP e aggiungono parecchi metodi utili. Se non vuoi la conversione automatica, la personalizzazione è semplice: ti basta ridefinire il metodo getDates. Per disattivarla del tutto, restituisci un array vuoto dal metodo getDates. Ecco un esempio:
public function getDates()
{
return ['created_at'];
}Se una colonna è trattata come data, hai quattro possibilità: un timestamp UNIX, una stringa di data (Y-m-d), una data-ora o un’istanza DateTime/Carbon.
Accessor e mutator
Come i getter e i setter di qualunque linguaggio, accessor e mutator formattano gli attributi Eloquent prima di leggerli o di scriverli sulle istanze del modello. La differenza è che gli accessor servono a leggere i dati, mentre i mutator si occupano di modificarli.
Per definire un accessor dichiari il metodo getFooAttribute sul modello, il nome del metodo va scritto in camel case, anche se il nome della colonna è tutto minuscolo.
class User extends Model {
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}Un mutator si definisce allo stesso modo: usa setFooAttribute, di nuovo rispettando il camel case.
class User extends Model {
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}Soft delete
Il soft delete non elimina la riga dal database: aggiunge al record un timestamp deleted_at a parte. Per attivarlo sul tuo modello, applica il trait SoftDeletes.
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
}Il metodo softDeletes() aggiunge la colonna deleted_at nella migration. Una migration non è altro che la gestione del database in PHP invece che in SQL.
$table->softDeletes();In certi casi vuoi che una query mostri anche i record eliminati in soft delete: per questo c’è withTrashed().
Se invece nei risultati vuoi soltanto i modelli eliminati in soft delete, usa il metodo onlyTrashed().
$student = Student::onlyTrashed()->where('account_id', 1)->get();Dopo tutte queste operazioni, per rimettere in attivo i modelli eliminati in soft delete usa il metodo restore.
$student->restore();restore() si può usare anche direttamente nella query.
Student::withTrashed()->where('account_id', 1)->restore();Se dopo il soft delete vuoi eliminare il modello dal database in modo definitivo, usa il metodo forceDelete().
$student->posts()->forceDelete();Per sapere se un modello è stato eliminato in soft delete, hai il metodo trashed().
if ($student->trashed())
{
//Todo
}Conclusione
Laravel è uno dei framework PHP più conosciuti ed Eloquent rende davvero semplice il dialogo con il database. In questo articolo abbiamo visto alcune delle sue funzionalità più importanti. Ce ne sono molte altre e puoi approfondirle qui. Segui il link e scopri tutto quello che Laravel Eloquent sa fare.


