本教程是Laravel手冊的一部分。從此處下載 。

現在,讓我們重新實現第一個項目,這次當未登錄時顯示狗的列表,但只允許已登錄的使用者修改數據。

首先,我們創建一個新的遷移:

php artisan make:migration create_dogs_table

打開新創建的遷移文件,在我這裡是 database/migrations/2023_05_12_164831_create_dogs_table.php

<?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');
    }
};

我們只需稍微修改遷移,添加了狗的名稱:

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

保存文件,返回終端,運行 php artisan migrate

現在,讓我們脚手架Dog模型:

php artisan make:model Dog

打開 routes/web.php

在頂部,添加:

use App\Models\Dog;

然後找到 / 路由:

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

將其更改為以下内容,以檢索狗的列表並將其傳遞給標記為index的視圖:

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

現在在 resources/views/welcome.blade.php 中,我們可以使用 @foreach 循環遍歷狗的數組,代碼如下:

<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>已登錄</p>
    @endauth

    @guest
    <p>未登錄</p>
    @endguest
</div>

如果刷新首頁,將會發現沒有任何變化,因為列表中沒有狗的數據。

實際上,我們可以使用 @forelse 來顯示“空狀態”。

將以下代碼:

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

更改為:

@forelse ($dogs as $dog)
    <li class="flex mb-1">
        <span class="flex-1">{{ $dog->name }}</span>
    </li>
@empty
    <p>還沒有狗</p>
@endforelse

我們表中還沒有狗,但是您可以使用以下SQL查詢在數據庫中插入數據,這裡需要打開TablePlus

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

現在,當我們登錄時,我們希望顯示添加新狗的表單,並在列表中為每只狗顯示删除按鈕。

首先,在 Dog 模型類中,將 name 添加到名為 $fillable 的數組中:

protected $fillable = ['name'];
<?php

namespace App\Models;

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

class Dog extends Model
{
    use HasFactory;

    protected $fillable = ['name'];
}

我們創建一個名為 DogController 的控制器:

php artisan make:controller DogController

這將創建 app/Http/Controllers/DogController.php 文件:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DogController extends Controller
{
    //
}

在頂部添加使用 App\Models\Dog;,然後向類中添加這兩個方法 createdelete,與之前一樣,但這次都會先檢查用戶是否已登錄:

<?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 redirect()->route('index');
    }

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

        return redirect()->route('index');
    }
}

接下來,在 routes/web.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');

現在,我們可以在 resources/views/welcome.blade.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>還沒有狗</p>
@endforelse

我們將它包裝在 @auth 中,以使其僅在登錄時可見。

嘗試點擊一個“Delete”按鈕,對應的行應該會消失。

如果未登錄,當前顯示如下:

現在,讓我們添加一個添加新狗的表單。以前我們使用了一個部分視圖,為了展示如何使用部分視圖,但現在讓我們直接將它添加到welcome 模板中:

@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

以下是完整的代碼供參考:

<!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') }}">Dashboard</a>
            @else
                <a href="{{ route('login') }}">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>