This tutorial is part of the Laravel Handbook. Download it from https://flaviocopes.com/access/
In this tutorial, we will be implementing the ability for authenticated users to add items to the database. Unlike our previous project, this time we will display the list of dogs even when users are logged out, but only logged-in users will have permission to modify the data.
To begin, let’s create a new migration for the “dogs” table:
php artisan make:migration create_dogs_table
Open the newly created migration file, which is located at database/migrations/2023_05_12_164831_create_dogs_table.php
, and update it as follows:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('dogs', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('dogs');
}
};
Save the file and run php artisan migrate
in your terminal to apply the migration.
Next, let’s scaffold the “Dog” model:
php artisan make:model Dog
In the routes/web.php
file, add the following line at the top to import the Dog
model:
use App\Models\Dog;
Then, locate the /
route and update it as follows, which retrieves the list of dogs and passes it to the “welcome” view:
Route::get('/', function () {
$dogs = Dog::all();
return view('welcome', ['dogs' => $dogs]);
})->name('index');
Now, open the resources/views/welcome.blade.php
file and modify it to loop over the dogs array using @foreach
directive:
<h1 class="pb-2 mb-3 font-bold border-b border-b-gray-300">
Dogs
</h1>
<div>
@foreach ($dogs as $dog)
<li class="flex mb-1">
<span class="flex-1">{{ $dog->name }}</span>
</li>
@endforeach
@auth
<p>Logged in</p>
@endauth
@guest
<p>Not logged in</p>
@endguest
</div>
Now, if you refresh the home page, you’ll see the list of dogs. However, since we don’t have any dogs in the database yet, the list will be empty.
To display an “empty state” when there are no dogs, you can use the @forelse
directive instead of @foreach
. Update the code in resources/views/welcome.blade.php
as follows:
@forelse ($dogs as $dog)
<li class="flex mb-1">
<span class="flex-1">{{ $dog->name }}</span>
</li>
@empty
<p>No dogs yet</p>
@endforelse
To add some dogs to the database, you can use SQL queries in a tool like TablePlus. Here’s an example SQL query to insert some dog data:
INSERT INTO "dogs" ("id", "name", "created_at", "updated_at") VALUES
('1', 'Roger', '2023-05-11 09:27:20', '2023-05-11 09:27:20'),
('2', 'Syd', '2023-05-11 09:29:52', '2023-05-11 09:29:52'),
('3', 'Botolo', '2023-05-11 09:29:57', '2023-05-11 09:29:57'),
('4', 'Zoe', '2023-05-11 09:30:12', '2023-05-11 09:30:12');
Now, we’ll add the ability to add and delete dogs. First, let’s update the Dog
model to include the name
attribute in the $fillable
array:
protected $fillable = ['name'];
Next, let’s create a controller named DogController
:
php artisan make:controller DogController
Inside the DogController.php
file, add the following lines at the top to import the necessary classes:
use App\Models\Dog;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
Then, add the create
and delete
methods to the DogController
class, which will handle the logic for adding and deleting dogs. Both methods will first check if the user is logged in before performing any actions:
public function create(Request $request)
{
if (Auth::check()) {
$this->validate($request, [
'name' => 'required',
]);
Dog::create($request->all());
}
return redirect()->route('index');
}
public function delete($id)
{
if (Auth::check()) {
$dog = Dog::find($id);
$dog->delete();
}
return redirect()->route('index');
}
Next, add the routes for creating and deleting dogs in the routes/web.php
file:
use App\Http\Controllers\DogController;
//...
Route::post(
'/dogs',
[DogController::class, 'create']
)->name('dog.create');
Route::delete(
'/dog/{id}',
[DogController::class, 'delete']
)->name('dog.delete');
Finally, update the resources/views/welcome.blade.php
file to include buttons for deleting dogs and a form for adding new dogs:
@forelse ($dogs as $dog)
<li class="flex mb-1">
<span class="flex-1">{{ $dog->name }}</span>
@auth
<form action="{{ route('dog.delete', $dog->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit" class="p-1 bg-gray-200 border border-black">Delete</button>
</form>
@endauth
</li>
@empty
<p>No dogs yet</p>
@endforelse
@auth
<form method="post" action="{{ route('dog.create') }}">
@csrf
<h3 class="pb-2 mt-4 mb-3 font-bold border-b border-b-gray-300">Add a new dog</h3>
<div class="flex">
<div class="flex-1">
<label>Name</label>
<input type="text" name="name" id="name" class="p-1 border border-gray-200">
</div>
<input type="submit" name="send" value="Submit" class="p-1 bg-gray-200 border border-black cursor-pointer">
</div>
</form>
@endauth
That’s it! Now, when logged in, you’ll see a form to add a new dog and a delete button next to each dog in the list. When logged out, you will only see the list of dogs.
Tags: Laravel, Authentication, Database, CRUD