23 Eloquent

In questa parte ci soffermeremo sulla parte M dell’ MVC, i Models o Modelli e vedremo come laravel permetta la mappatura di una tabella di un database con una classe.

Infatti sarà possibile interagire tramite la classe con i dati di una tabella.

Eloquent è un ORM ovvero Object Relational Mapping che implementa l’ ActiveRecord, quindi permette e facilita l’associazione tra classe e tabella mediante una classe chiamata model.

Per comprendere meglio la stessa cosa fatta con le query grezze e poi con il QueryBuilder la effettueremo con Eloquent e quindi i Models e vedremo come sarà ancora più semplice ed intuitivo lavorare con il database.

Eloquent SELECT

Analizziamo subito il model app/Models/Album.php

use Illuminate\Database\Eloquent\Model;

class Album extends Model
{

}

abbiamo la classe Album che estende la classe Model.

  • Avevamo anche detto che la classe mappa il nome della tabella, in singolare e con l’iniziale maiuscola.
  • Abbiamo altresì enunciato che qualora la classe non corrisponda al nome plurale della tabella, dobbiamo specificarlo con una variabile protetta all’interno della classe.
  • Inoltre se il nome della primary key della tabella non corrisponde ad id, andrà anch’essa specificata come proprietà protetta all’interno della classe
class Album extends Model
{

 protected $table = 'Albo';

 protected $primaryKey = 'album_id';

}

Passando alla pratica andiamo nel metodo index() del controller e trasformiamolo utilizzando il model, importiamo la classe Album

use App\Models\Album;

togliamo la parte della facade DB e sostituiamola con la classe Album.

Il model eredita anche tutto il querybuilder

Il primo metodo richiamato dalla classe deve essere richiamato staticamente ::

$queryBuilder = Album::orderBy('id', 'DESC');

abbiamo sostituito DB::table(‘albums’) con Album. Tutto il resto rimane invariato con il querybuilder.

Eloquent DELETE

Continuiamo sostituendo DB::table(‘albums’) con Album

1 modo

public function destroy(int $album) {  
  $res = Album::where('id', $id)->delete();
  return $res;
}

Molto semplice!

2 modo

possiamo fare di più, passiamo semplicemente usare il metodo destroy() che restituisce un intero. Compatta maggiormente il codice e restituiamo già l’operazione richiesta

return Album::destroy($id);

con una semplice e corta riga ho già creato il metodo delete.

3 modo

Volendo possiamo usare un altro metodo e dire a laravel di iniettare un’istanza di Album come parametro al metodo destroy() e poi chiamare il metodo delete() che restituisce un bool o null e facciamo un cast a integer aggiungendo un segno + davanti a $album

public function destroy(Album $album) {
  return +$album->delete();
}

Eloquent UPDATE

Senza bisogno di troppe parole sostituiamo il querybuilder DB::table(‘albums’)-> con il model Album::

$res = Album::where('id', $id)->update(
 ['album_name' => request()->input('name'),
  'description' => request()->input('description')
 ]
);

Ricordo sempre che il primo metodo viene invocato statico Album::where .

Un’altra precisazione è quella che avevamo creato il metodo store() nel controller per fare l’aggiornamento, in realtà con il resource controller il metodo che viene creato è update()

public function update(Request $request, $id)
{
 $res = Album::where('id', $id)->update(
  ['album_name' => request()->input('name'),
   'description' => request()->input('description')
  ]
 );
 $messaggio = $res ? 'Album con id = ' . $id . ' Aggiornato' : 'Album ' . $id . ' Non aggiornato';
  session()->flash('message', $messaggio);
 return redirect()->route('albums.index');
}

Eloquent INSERT

Anche qui, nel resource controller il metodo che viene creato è store() e non save().

Abbiamo alcune strade diverse, possiamo usare insert()

$res = Album::insert(
 [
  'album_name' => request()->input('name'),
  'album_thumb' => '/',
  'description' => request()->input('description'),
  'user_id' => 1
 ]
);

oppure possiamo usare il metodo create() tipico solo dei models.

$res = Album::create(

Con questo metodo si attiva una protezione di laravel chiamata mass assignment execution che non permette la scrittura. Per utilizzarlo dobbiamo indicare che i campi passati sono scrivibili perchè un malintenzionato passando dalla sessione potrebbe inserire dei campi con un l’id di un utente non autorizzato. Per far questo nel model Album dobbiamo specificare in una variabile protetta un array dei campi su cui scrivere

protected $fillable = ['album_name','description'];

Se per esempio volessimo che l’amministratore voglia aggiungere lo user_id, lo inseriamo.

Un terzo metodo per inserire un nuovo album escludendo il problema della protezione è quello di istanziare un nuovo oggetto Album

$album = new Album();

a questo punto indichiamo le colonne come proprietà del nuovo oggetto e assegniamo il valore

$album->album_name = request()->input('name');
$album->description = request()->input('description');
$album->user_id = 1;

infine, una volta inseriti tutti i campi compilati chiamiamo il metodo save()

$res = $album->save();

Eloquent UPDATE

Per l’aggiornamento possiamo fare la stessa cosa

$res = Album::where('id', $id)->update(
 ['album_name' => request()->input('name'),
  'description' => request()->input('description')
 ]

Ma possiamo anche fare diversamente, prima cercare l’album tramite il metodo find()

$album = Album::find($id);

poi cambiamo i campi da aggiornare

$album->album_name = request()->input('name'),
$album->description = request()->input('description')

infine salviamo con il metodo save() usato anche prima, l’unica differenza è che eloqunt si accorge che l’id dell’utente esiste già e sovrascrive i records anzichè crearne uno nuovo

$res = $album->save();

SHOW

public function show( $id)
{
    $sql = 'select * FROM albums WHERE id=:id';
    return  DB::select($sql, ['id' => $id]);
}

Iniettiamo il model come parametro del metodo show( Album )

* @param  \App\Models\Album  $album

public function show(Album $album) {

a questo punto restituiamo semplicemente $album

return $album;