# Only authenticated users can add items to the database

> Learn how to restrict data changes in Laravel so only authenticated users can add or delete records, using Auth::check and the @auth and @guest directives.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2023-06-21 | Topics: [Laravel](https://flaviocopes.com/tags/laravel/) | Canonical: https://flaviocopes.com/only-authenticated-users-can-add-items-to-the-database/

Now let’s re-implement what we did in the first project but this time we show the dogs list when logged out, but we’ll only allow logged in users to modify the data.

First we create a new migration:

```shell
php artisan make:migration create_dogs_table
```

Open the newly created migration file, in my case `database/migrations/2023_05_12_164831_create_dogs_table.php` 

```shell
<?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->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('dogs');
    }
};
```

We just modify the migration a little adding a name for the dog:

```shell
Schema::create('dogs', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});
```

Save the file, go back to the terminal, run `php artisan migrate`

![Terminal showing successful migration output with create_dogs_table migration completed](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/1.webp)

Now we scaffold the Dog model:

```shell
php artisan make:model Dog
```

Go to `routes/web.php`.

At the top, add

```php
use App\Models\Dog;
```

then find the `/` route:

```php
Route::get('/', function () {
    return view('welcome');
});
```

and change it to this to retrieve the dogs list and pass it to the view, which we label `index`:

```php
Route::get('/', function () {
    $dogs = Dog::all();
    return view('welcome', ['dogs' => $dogs]);
})->name('index');
```

Now in `resources/views/welcome.blade.php` we can loop over the dogs array using `@foreach` like this:

```php
<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>
```

If you refresh the home you’ll see nothing changed because we don’t have any dog in the list.

![Web page showing Dogs heading with no content displayed because there are no dogs in the database yet](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/2.webp)

We can actually show an “empty state” using `@forelse`.

Instead of 

```php
@foreach ($dogs as $dog)
  <li class="flex mb-1">
      <span class="flex-1">{{ $dog->name }}</span>
  </li>
@endforeach
```

use this:

```php
@forelse ($dogs as $dog)
  <li class="flex mb-1">
      <span class="flex-1">{{ $dog->name }}</span>
  </li>
@empty
    <p>No dogs yet</p>
@endforelse
```

![Web page showing Dogs heading with No dogs yet message displayed using the forelse empty state](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/3.webp)

We don’t have dogs in the table yet, but you can open the database using [TablePlus](https://tableplus.com/) and insert data using this SQL query:

```php
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');
```

![TablePlus database interface showing the dogs table with four inserted records: Roger, Syd, Botolo, and Zoe](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/4.webp)

Now when we’re logged in I want to display the form to add a new dog, and the delete button for each dog in the list.

First, inside the `Dog` model class we add the `name`  to an array named `$fillable`:

```php
protected $fillable = ['name'];
```

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Dog extends Model
{
    use HasFactory;
		protected $fillable = ['name'];
}
```

We create a controller named `DogController`:

```php
php artisan make:controller DogController
```

This created the `app/Http/Controllers/DogController.php` file:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DogController extends Controller
{
    //
}
```

Add **`use`** `App\Models\Dog;` at the top, and add those 2 methods to the class, `create` and `delete`, as we did before, but this time both first check that the user is logged in:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\Dog;

class DogController extends Controller
{
    public function create(Request $request)
    {
        if (Auth::check()) {
            $this->validate($request, [
                'name' => 'required',
            ]);
            Dog::create($request->all());
        }
        return to_route('index');
    }

    public function delete($id)
    {
        if (Auth::check()) {
            $dog = Dog::find($id);
            $dog->delete();
        }

        return to_route('index');
    }
}
```

Ok now we need a route to add a a new dog, and one to delete a dog. In `routes/web.php`, add:

```php
use App\Http\Controllers\DogController; 

//...

Route::post(
    '/dogs',
    [DogController::class, 'create']
)->name('dog.create');

Route::delete(
    '/dog/{id}',
    [DogController::class, 'delete']
)->name('dog.delete');
```

Now we can display the buttons to remove dogs in `resources/views/welcome.blade.php`:

```php
@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
```

We wrap it into `@auth` to make it only visible if logged in.

![Web page showing list of dogs with Delete buttons next to each name, visible only when user is logged in](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/5.webp)

Try clicking one “delete” button, the corresponding row should disappear.

If logged out, here’s what you see:

![Web page showing list of dogs without any Delete buttons, displayed when user is logged out](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/6.webp)

Now let’s add the form to add a new dog. Before we used a partial, to see how you can use partials, but now let’s just add it to the `welcome` template:

```php
@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

```

Here’s the full code for reference:

```php
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    @vite('resources/css/app.css')
</head>

<body class="p-4">

    @if (Route::has('login'))
        <div class="text-right">
            @auth
                <a href="{{ url('/dashboard') }}" class="">Dashboard</a>
            @else
                <a href="{{ route('login') }}" class="">Log in</a>
                @if (Route::has('register'))
                    <a href="{{ route('register') }}" class="ml-4">Register</a>
                @endif
            @endauth
        </div>
    @endif

    <h1 class="pb-2 mb-3 font-bold border-b border-b-gray-300">
        Dogs
    </h1>

    <ul>
        @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
    </ul>

    @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

</body>

</html>
```

![Web page showing complete interface with dogs list, delete buttons, and Add a new dog form at bottom](https://flaviocopes.com/images/only-authenticated-users-can-add-items-to-the-database/7.webp)
