Laravel 8.x
Route::group(['prefix' => '/seeds-transactions'], function () {
Route::post('/', [SeedsTransactionsController::class, 'store']);
Route::put('/{seeds_transaction}', [SeedsTransactionsController::class, 'update']);
Route::delete('/{seeds_transaction}', [SeedsTransactionsController::class, 'destroy']);
});
Laravel 9.x
Route::controller(SeedsTransactionsController::class)->group(function() {
Route::post('/seeds-transactions', 'store');
Route::put('/seeds-transactions/{seeds_transaction}', 'update');
Route::delete('/seeds-transactions/{seeds_transaction}', 'destroy');
}
Laravel 8.x
class CreateUsersTable extends Migration {
[...]
}
Laravel 9.x
return new class extends Migration {
[...]
}
User.php
public function licences() {
return $this->hasMany(Licence::class);
}
Laravel 8.x
Route::get('/users/{user}/licences/{licence:id}', 'show');
Laravel 9.x
Route::get('/users/{user}/licences/{licence}', 'show')->scopeBindings();
Requires XDebug with XDebug coverage mode enabled
Laravel 8.x
php artisan test
Laravel 9.x
XDEBUG_MODE=coverage php artisan test --coverage --min=80
Laravel 8.x
Migration
$table->text('licence_notes');
Controller
Licence::whereLike('licence_notes', 'LIKE', '%text%');
Laravel 9.x
Migration
$table->text('licence_notes')->fulltext(); //Creates FULLTEXT index in MySQL table
Controller
Licence::whereFullText('licence_notes', '%text%'); //Uses MySQL MATCH AGAINST functionality
Laravel 8.x
Enum
final class LicenceStatus extends Enum {
const Expired = 'Expired';
const Active = 'Active';
}
Migration
$table->enum('licence_status', [LicenceStatus::Active, LicenceStatus::Expired]);
Laravel 9.x
Enum
enum LicenceStatus:string {
case Expired = 'Expired';
case Active = 'Active';
}
Migration
$table->string('licence_status')->default('active');
Model
protected $casts = ['licence_status' => LicenceStatus::class]