昨天我們看完前端的介紹,接著我們要繼續進行我們報名表的修改,之後在寫的時候大多也是以這樣的節奏,先寫新增再處理儲存,接下來是修改然後更新,再來是刪除,依需求看需不需要show和index。照著這樣的順序之後自己處理時就比較不會亂了手腳。
那我們要怎麼修改呢?我們不太能像之前的article去做他的修改,所以我們將他放在article的show中,去做判斷看他有沒有寫過,有寫過就幫我們進到修改之中,那我們先開啟resources\views\articles\show.blade.php
:
@auth
@if(auth() -> user() -> joinArticles -> find($article -> id))
<div class=" ">
<form method=" " action="{{ route('joiners.edit', $article) }}">
@csrf
<button class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("修改報名資料")}} </button>
</form>
</div>
@else
<div class=" ">
<form method=" " action="{{ route('joiners.create') }}">
@csrf
<button name="article" value="{{ $article->id }}" class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("我要報名!")}} </button>
</form>
</div>
@endif
@else
<div class=" ">
<form method=" " action="{{ route('joiners.create') }}">
@csrf
<button name="article" value="{{ $article->id }}" class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("我要報名!")}} </button>
</form>
</div>
@endauth
這段程式碼有些複雜,我們先拆成兩部分來看第一段是:
@if(auth() -> user() -> joinArticles -> find($article -> id))
<div class=" ">
<form method=" " action="{{ route('joiners.edit', $article) }}">
@csrf
<button class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("修改報名資料")}} </button>
</form>
</div>
@else
<div class=" ">
<form method=" " action="{{ route('joiners.create') }}">
@csrf
<button name="article_id" value="{{ $article->id }}" class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("我要報名!")}} </button>
</form>
</div>
@endif
這其中判斷的是判斷這個使用者在這個多對多的表格中是否存在著這篇articlek的id,若是之前就存在就代表他已經填寫過其報名表。那我們就該讓他只做修改的動作,但若是沒有的話就讓他可以報名。
那剩下程式的程式碼就比較容易懂了,他是先判斷了auth
,判斷這個人有沒有登錄,若是他沒有登陸的話就直接顯示報名的按鈕,不需做判斷。
寫完之後我們就可以直接進入controller中寫我們的edit了,app\Http\Controllers\JoinerController.php
:
/**
* Show the form for editing the specified resource.
*/
public function edit($article)
{
$article = auth() -> user() -> joinArticles -> find($article);
return view('joiners.edit', ['article' => $article]);
}
接著把edit的blade寫好,他和之前的edit一樣,和create的長得幾乎一模一樣,只有有些地方不同。
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{$article->title}}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 m-6 text-center">
@if($errors->any())
<div class = "error p-3 bg-red-150 text-white font-thin rounded">
<ul>
@foreach($errors -> all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class = "text-lg text-gray-700 py-2 px-6 whitespace-pre-wrap leading-relaxed text-left">
{{ $article -> summary }}
</div>
<form action = "{{ route('joiners.update', $article) }}" method = "post">
@csrf
@method('patch')
<div class="field my-2">
<lable for="" > {{__("生日")}} </lable>
<input type = "date" disabled value="{{ $article -> pivot -> birthday }}" name = "birthday" class = "border-gray-300 p-2 mx-2 disabled:bg-slate-50 disabled:text-slate-500">
</div>
<div class="flex-auto ">
<div class="field my-2" ><p>{{__("身分證字號")}}</p></div>
<div class="field my-2 ">
<lable for="" class="mb-2"> {{__("")}}</lable>
<input type = "text" disabled value="{{ $article -> pivot -> ID_number }}" name = "ID_number" class = "w-2/5 border-gray-300 p-2 mx-2 disabled:bg-slate-50 disabled:text-slate-500">
</div>
</div>
<div class="flex-auto ">
<div class="field my-2" ><p>{{__("電話號碼")}}</p></div>
<div class="field my-2 ">
<lable for="" class="mb-2" > {{__("")}}</lable>
<input type = "text" disabled value="{{ $article -> pivot -> phone }}" name = "phone" class = "w-2/5 border-gray-300 p-2 mx-2 placeholder-gray-300 disabled:bg-slate-50 disabled:text-slate-500" placeholder="{{ __('ex:0912345678') }}">
</div>
</div>
<div class="flex-auto ">
<div class="field my-2" ><p>{{__("備註")}}</p></div>
<div class="field my-2" >
<lable for="" class="mb-2"> {{__("")}} </lable>
<textarea name = "note" rows = "5" class = "w-4/5 m-auto border-gray-300 p-2 placeholder-gray-300" placeholder="{{ __('有甚麼話想對主辦方說的嗎...') }}">{{ $article -> pivot -> note }}</textarea>
</div>
</div>
<div class="flex mt-4 space-x-6 justify-center">
<div class="actions">
<button class="px-3 py-1 rounded bg-indigo-150 text-white hover:bg-indigo-250"> {{__("確定修改")}} </button>
</div>
<div class="px-3 py-1 rounded bg-gray-200 hover:bg-gray-300 ">
<a href = "{{route('dashboard')}}" > {{__("取消修改")}} </a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
這邊的取資料方法我們改天會有比較詳細的說明,但是它的概念是和之前一樣的,就是去資料庫中取以前的資料來前端存放,但是我們這次的edit有一點點不同,我們除了前面幾個都加了一個新的屬性
<input type = "date" disabled value="{{ $article -> pivot -> birthday }}" name = "birthday" class = "border-gray-300 p-2 mx-2 disabled:bg-slate-50 disabled:text-slate-500">
不知道你有沒有發現我們加上了disabled
,我們讓使用者除了備註以外其餘都不可去做更改,雖然更新只是一個小動作但是我們認為那些資料大部分都不會做修改,那我們就不用花費這個時間去讓資料庫重新更新那些未更改的資料,所以我們將他鎖了起來。
之後我們就回到controller中去將他的update和delete一次寫好再來處理delete的入口,那我們到app\Http\Controllers\JoinerController.php
:
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $article)
{
$article = auth() -> user() -> joinArticles -> find($article);
$content = $request->validate([
'note' => 'max:255'
]);
$article -> update($content);
auth()->user()->joinArticles()->syncWithoutDetaching([$article -> id => $content]);
return redirect() -> route('dashboard');
}
/**
* Remove the specified resource from storage.
*/
public function destroy($article)
{
auth()->user()->joinArticles()->detach($article);
return redirect() -> route('dashboard');
}
這邊的寫法應該和之前的用法差不多,但是我們這邊的用法是用 detach
去做刪除,是不是可以清楚地感覺到一對多和多對多的差異了。
那我們去寫他的入口吧,我們將他放在修改報名表資料的那個頁面中,那我們移動到resources\views\joiners\edit.blade.php
,並加入程式碼:
<form method="POST" action="{{ route('joiners.destroy', $article) }}">
@csrf
@method('delete')
<button type = "submit" class = "px-3 py-1 rounded bg-red-150 text-white hover:bg-red-250"> {{__("取消報名")}} </button>
</form>
那這樣我們就完成今天的作業啦!而我們也基本完成了報名的基本功能,目前的報名功能對於使用者來說應該已經相對完整了,之後我們還有活動方的部分要完成,大家就跟著我們踏著曾經的笑和累一起走下去吧,明天要寫查看活動。希望各位魔法師的魔杖還好的沒有斷,我們明天見,掰掰!