Laravel Basic Laravel Knowledge Test: Solution

Task 1. Routes: Route with Single Action Controller.

Link to the / endpoint Controller.

routes/web.php:

Route::get('/', \App\Http\Controllers\HomeController::class);

Link to the documentation.


Task 2. Validation: Validation with Form Request.

Create a Form Request using an Artisan command and add rules inside the rules() method.

Solution code:

php artisan make:request StorePostRequest

app/Http/Requests/StorePostRequest.php:

class StorePostRequest extends FormRequest
{
public function rules(): array
{
return [
'title' => ['required'],
'body' => ['required'],
];
}
 
public function authorize(): bool
{
return true;
}
}

Link to the documentation.


Task 3. File Uploads: Update: Delete Old File.

Delete the old file using the delete() method on the Storage facade.

Solution code:

app/Http/Controllers/PostController.php:

use Illuminate\Support\Facades\Storage;
 
class HouseController extends Controller
{
// ...
 
public function update(Request $request, House $house)
{
$filename = $request->file('photo')->store('posts');
 
Storage::delete($post->photo);
 
$post->update([
'title' => $request->title,
'body' => $request->body,
'photo' => $filename,
]);
 
return 'Success';
}
 
// ...
}

Link to the documentation.


Task 4. Eloquent with Relations: BelongsToMany - Extra Fields in Pivot Table.

Define the pivot table name with the foreign keys on the Team model's users relationship For the users relationship define the position DB column and timestamps.

Solution code:

app/Models/Team.php:

use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class Team extends Model
{
protected $fillable = [
'name',
];
 
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class)
->withPivot('position')
->withTimestamps();
}
}

Task 5. Eloquent Basics: Update or New Record.

Eloquent has a method for updating or creating a method called updateOrCreate. This method accepts two array parameters: the first is by which DB fields to search, and the second is the DB fields for creating a new record or updating.

Solution code:

app/Http/Controllers/UserController.php:

class UserController extends Controller
{
// ...
 
public function check_update(string $name, string $email)
{
$user = User::updateOrCreate([
'name' => $name,
], [
'email' => $email,
'password' => str()->password(),
]);
 
return view('users.show', compact('user'));
}
 
// ...
}

Link to the documentation.


Task 6. Migrations: Auto-Delete Related Records

Add the cascadeOnDelete() method to the foreign ID.

Solution code:

database/migrations/task6/xxx_create_products_table.php:

Schema::create('products', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id')->constrained()->cascadeOnDelete();
$table->string('name');
$table->timestamps();
});

Link to the documentation.


Task 7. Auth: Password with Letters

Modify the password rule in the app/Http/Controllers/Auth/RegisteredUserController.php.

Solution code:

app/Http/Controllers/Auth/RegisteredUserController.php:

 
class RegisteredUserController extends Controller
{
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()->letters()],
]);
 
// ...
}
}

Additionally, you can set the default password in the Service Provider and call Password::defaults() to have the same password validation rule everywhere in the application.

app/Providers/AppServiceProvider.php:

use Illuminate\Validation\Rules\Password;
 
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Password::defaults(function () {
return Password::min(8)
->letters();
});
}
}

Link to the documentation.


Task 8. Blade: Loop in the Table.

Instead of @if, use the @forelse with the @empty Blade directive.

Solution code:

resources/views/users/index.blade.php:

// ...
<tbody>
@forelse ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->created_at }}</td>
</tr>
@empty
<tr>
<td colspan="3">No content.</td>
</tr>
@endforelse
</tbody>
// ...

Link to the documentation.