16 Controller e Raw query

Vediamo come interrogare il database con delle queries grezze utilizzando la classe facade DB.

Vediamo come selezionare i dati precedentemente inseriti nel database creando un controller e nella vista invece che utilizzare una funzione anonima, usiamo il controller col suo metodo

Creare un controller

Creiamo un nuovo controller per gli album, ricordo di usare –help per la guida

php artisan make:controller AlbumsController -m Album -r

Il nome del controller è uguale al nome della tabella con l’iniziale maiuscola seguita dalla keyword Controller

l’opzione -m lega il controller ad un model, bisogna quindi specificarne il nome.

l’opzione -r genera un resource controller, ovvero tutte quelle funzioni legate alla manipolazione dei dati della tabella.

Struttura di un controller

public function index()

Abbiamo il metodo index() per mostrare l’elenco dei dati, nel nostro caso l’elenco degli album

public function create()

Il metodo create() per mostrare il form

public function store(Request $request)

Il metodo store() per salvare i dati

public function show(Album $album)

Il metodo show() per mostrare un record

public function edit(Album $album)

Il metodo edit() per modificare un record

public function update(Request $request, Album $album)

Il metodo update() per aggiornare, come si vede ignetta la Request e automaticamente passando l’ID ci crea un’istanza dell’oggetto

public function destroy(Album $album)

Il metodo destroy() elimina un record passando il suo ID

Mappare il controller nella rotta

In web.php andiamo a fare un po’ di pulizia, lasciamo solo le 3 rotte / , /users , /albums.

Nell’uso dei modelli e dei controller avevamo:

use App\Http\Controllers\{HomeController, WelcomeController};
use App\Models\User;
use \App\Models\Album;

Le ultime 2 le raggruppiamo con le graffe, visto che il percorso è identico

use App\Models\{User, Album};

Per i controllers cancelliamo i precedenti visto ce non servono più e inseriamo solo AlbumsController

use App\Http\Controllers\AlbumsController;

Nella rotta /albums invece della funzione passiamo il controller all’interno di un array che conterrà la classe del controller come primo valore e il metodo da eseguire come secondo

Route::get('/albums', [AlbumsController::class , 'index']);

Nel metodo index() del controller andiamo a restituire il metodo all() che è simile al metodo get(), ma non permette la concatenazione di altri metodi.

public function index()
{
 return Album::all();
}

Proviamo a lanciare l’url e vediamo che tutto funziona correttamente come prima.

Raw query

Supponiamo invece di non avere il model Album e volessimo effettuare un interrogazione del database direttamente dal metodo index utilizzando delle queries grezze, inseriamo il comando SQL in una variabile

public function index()
{
 $sql = 'select * from albums';
}

a questo punto utilizziamo la facade DB utilizzando il suo metodo select()

$sql = 'select * from albums';
return DB::select($sql);

Il metodo select() ci restituisce un array di records e ogni record è la standard class corrispondenti alle proprietà della tabella.

Testiamo e vediamo che la pagina si apre correttamente con tutti i records visualizzati correttamente.

Se volessimo filtrare i record, magari via Get passando come parametro l’ID,

http://127.0.0.1:8000/albums?id=2

possiamo iniettare la Request di DB come parametro del metodo index()

public function index(Request $request)
{
 $sql = 'select * from albums';
 return DB::select($sql);
}

adesso possiamo andare a mettere un condizione che se $request ha un ID, concateniamo un where alla $sql

$sql = 'select * from albums';
if($request->has('id')) {
$sql .= ' where id ='
}

aggiungiamo l’id prendendolo da $request->get(), magari facciamo anche un casting a integer

$sql .= ' where id ='. (int)$request->get('id');

Perfetto, ora vediamo solo il record 2.

Filtrare in base al nome

Se volessimo aggiungere la condizione di filtraggio in base anche al nome, la cosa si complica leggermente, perchè non potremmo effettuare il cast a intero come per l’id, l’obiettivo è di ottenere una query SQL così

select * from albumums WHERE id=2 AND album_name="pippo"

inizializziamo una variabile esterna agli if $where vuota. Poi costruiamo un altro if basato sul parametro album_name che popola la query con il frammento di SQL aggiuntivo.

Sommiamo $where a $sql

public function index(Request $request)
{
 $where = '';
 $sql = 'select * from albums';
 if($request->has('id')) {
  $sql .= ' where id =' . (int)$request->get('id');
 }

 if($request->has('album_name')) {
  $where = " AND album_name=".$request->get('album_name')." ";
 }

 $sql = $sql . $where;
 return DB::select($sql);
}

La procedura risulta abbastanza contorta, fortunatamente esistono i filtri PDO che ci verranno in contro e che vedremo più avanti.

Abbiamo la possibilità di testare come sta uscendo la query sfruttando la funzione dd() die dump di laravel

dd($sql);