/

只有驗證過的使用者可以新增項目到資料庫

只有驗證過的使用者可以新增項目到資料庫

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

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

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

1
php artisan make:migration create_dogs_table

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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');
}
};

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

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

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

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

1
php artisan make:model Dog

打開 routes/web.php

在頂部,添加:

1
use App\Models\Dog;

然後找到 / 路由:

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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 來顯示“空狀態”。

將以下代碼:

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

更改為:

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

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

1
2
3
4
5
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 的數組中:

1
protected $fillable = ['name'];
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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 的控制器:

1
php artisan make:controller DogController

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

1
2
3
4
5
6
7
8
9
10
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DogController extends Controller
{
//
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?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 中添加一個添加新狗的路由和刪除狗的路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 中顯示删除狗的按鈕:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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 模板中:

1
2
3
4
5
6
7
8
9
10
11
12
13
@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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!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>

tags: [“laravel”, “authentication”, “database”]