
La guida a Laravel 7 sta arrivando!
Laravel per Tutti sarà presto disponibile.
Resta in contatto, scegli tu il modo.
Ho deciso di aggiornare un mio vecchio articolo pubblicato sull'ormai defunto medium.com e adattarlo alla nuova versione di Laravel 7
Troverai alcune scorciatoie sempre valide e nuovi helper stratosferici per la gestione delle stringhe.
Cosa aspetti? Buona pratica!
1. Doppia condizione Where
Ti sarà sicuramente capitato di dover selezionare dalla tabella l'utente con nome Mario e cognome Rossi:
# Query SQL
SELECT * FROM `utenti`
WHERE
`nome` = 'Mario'
AND `cognome` = 'Rossi'
LIMIT 1
Utilizzando la sintassi del query builder di Laravel ti ritroveresti con questa porzione di codice:
// Un esempio potrebbe essere:
User::where("nome", 'Mario')->where("cognome", 'Rossi')->first();
// oppure anche:
User::where(["nome" => 'Mario', "cognome", 'Rossi'])->first();
Ecco invece un esempio di Clean code con laravel:
//Utilizzando AND:
User::whereNomeAndCognome('Mario','Rossi')->first();
//Con la stessa logica possiamo utilizzare anche OR:
User::whereNomeOrCognome('Mario','Rossi')->get();
2. Relazione belongsTo con valore di default
Realizzare un sistema per gestire i commenti di un blog è una pratica comune. Voglio analizzare con te un caso d'uso specifico: in caso di un commento di un utente "ospite" come gestire l'assenza dell'username?
Prova ad utilizzare la seguente sintassi:
//Funzione per gestire la relazione nel Model
public function user()
{
return $this->belongsTo('App\User')->withDefault([
'name' => 'Utente Anonimo',
]);
}
3. Redirect dal web.php
Ho visto alcuni progetti Laravel (piuttosto grandi) organizzati con un RedirectController
apposito per la gestione degli url: un bagno di sangue.
Esiste un particolare metodo che ti permetterà di farlo direttamente nel file delle routes:
// Tutti gli utenti che atterreranno su /prodotto-esaurito verranno reindirizzati su /prodotto-disponibile
Route::redirect('/prodotto-esaurito','/prodotto-disponibile',301);
4. Eliminare controller inutili
Hai una pagina statica "Chi sono", tutto il contenuto è presente nella view e nessuna variabile è istanziata nel controller. Praticamente sto parlando di questo caso particolare:
//Funzione nel controller relativo
public function about()
{
return view('about');
}
Se il tuo controller è davvero semplice e restituisce una vista, dovresti utilizzare il metodo apposito per le view:
//Ad esempio all'url home, richiamiamo la view index
Route::view('/home','homepage.index');
E, se proprio hai necessità di passare dei parametri puoi utilizzare:
//Ecco come passare un titile
Route::view('/home','homepage.index', ['title' => 'Chi sono']);
5. Crea il tuo menù dinamico
Un annoso problema è quello della gestione dei menù dinamici: la corretta applicazione della classe 'active'.
Lo step preliminare è quello di assegnare un nome a tutte le route. Utilizzare una variabile univoca ti permetterà di non incorrere in problemi di integrità dei dati nel caso l'url cambi.
//Esempio di una porzione di Route del file web.php
Route::view('/', 'homepage')->name('homepage');
Route::view('/about', 'about')->name('about');
Per gestire il menù invece dovrai utilizzare il request()->is()
, in questo modo:
<!--Layout tipico per gestire un menù HTML -->
<ul>
<li class="{{request()->is('home') ? 'active' : ''}}">Home</li>
<li class="{{request()->is('about') ? 'active' : ''}}">About</li>
</ul>
Per gestire gli eventuali url padre-figlio, come nell'esempio:
// Extra route di secondo livello
Route::view('/about/info', 'aboutinfo')->name('about.info');
Puoi semplicemente usare il carattere jolly * sul "padre" about:
<!--Layout tipico per gestire un menù HTML -->
<ul>
<li class="{{request()->is('home') ? 'active' : ''}}">Home</li>
<li class="{{request()->is('about*') ? 'active' : ''}}">About</li>
</ul>
la classe active sarà così applicata automaticamente a tutti gli url contenuti in 'about'
6. Refactoring di Auth::user()->id
Scrivere ogni volta Auth::user()->id
non è sbagliato, ma puoi scriverlo in un modo più performante:
//Primo metodo
Auth::id()
//Altro metodo utilizzando l'Helper auth()
auth()->id()
7. Ottimizzare la paginazione
Paginate o simplePaginate? La differenza c'è, ed è molto importante.
Come è facile intuire gli elementi della paginazione generati saranno diversi, in base al metodo utilizzato:
- Il metodo paginate(n) leggerà TUTTI i record della tabella, calcolerà il numero massimo di pagine e lo dividerà per n così da generare i vari indici. Lato grafico, visualizzerà a video un elemento HTML con i tasti Avanti, Indietro e le varie pagine con i numerini come indice. Questo metodo, su database di grandi dimensioni, NON è una best practices in termini prestazionali.
- Il metodo simplePaginate(n) si limiterà a leggere soltanto i primi n record inseriti. Lato grafico visualizzerà un elemento HTML con i tasti Avanti e Indietro. Il tasto avanti si occuperà di leggere i successivi n elementi.
// Richiamo il metodo paginate con n = 15
$users = Users::paginate(15);
// Richiamo il metodo DB::table() e successivamente la paginazione semplice con n = 15
$users = DB::table('users')->simplePaginate(15);
8. Mai più relazioni nulle
Utilizzando sempre l'esempio di un Blog, il caso d'uso in questione è la possibilità (non molto remota) che alcuni post non contengano commenti.
Come filtrare il tutto senza fare grossi giri con controlli o helper?
Normalmente si potrebbe utilizzare una struttura del genere:
// Assegno alla variabile $postsWithComments il risultato di questa query, senza gestire errori
$postsWithComments = BlogPost::with("comments")->get();
Ma per gestire eventuali BlogPost senza commenti associati si dovrebbe creare una struttura nel controller o nella view (pessima idea!) per non generare errori 404.
Gli helper di Laravel ci aiutano in questo modo:
$postsWithComments = BlogPost::with("comments")->has("comments")->get();
9. Lavora con le stringhe
Con Laravel 7 sono disponibili diversi metodi per manipolare le stringhe senza ricorrere alle funzioni PHP.
Prendendo come esempio questa stringa (spazi compresi, eh!):
//Dato iniziale
$stringa =' Buon Compleanno Taylor! ';
Dovrai rendere questa stringa uno slug: rimuovere gli spazi, rimuovere i simboli, rendere tutto minuscolo, e cambiare Taylor con Francesco.
Con PHP:
#PHP
strtolower(str_replace('Taylor', 'Francesco', trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $stringa), '-')));
Utilizzando gli helper di Laravel 7 invece:
#Laravel
Str::of($stringa)
->trim()
->replace('Taylor', 'Francesco')
->slug()
->lower();
10. Where Espressivo
Sempre rimanendo in tema di ottimizzazione del codice, è presente un piccolo trucchetto che renderà le tue query ancora più espressive.
//Classica query
$query = User::where('role', '=', 1)->get();
//Quey con uguaglianza sottintesa
$query = User::where('role', 1)->get();
//Query utilizzando il where<var>
$query = User::whereRole(1)->get();
Ovviamente questa cosa può essere utilizzata anche nel momento in cui si dovranno trattare dei campi timestamps in frontend.
$q->whereDate('created_at', date('Y-m-d'));
$q->whereDay('created_at', date('d'));
$q->whereMonth('created_at', date('m'));
$q->whereYear('created_at', date('Y'));
La guida a Laravel 7 sta arrivando!
Laravel per Tutti sarà presto disponibile.
Resta in contatto, scegli tu il modo.