前兩天認識完多對多,今天我們要來寫報名的基本功能,那我們也是先從新增開始寫。
首先我們一樣先到web去新增我們的路徑,讓之後使用時更容易。routes\web.php
:
Route::resource('joiners',\App\Http\Controllers\JoinerController::class)
->except('index')
->middleware(['auth', 'verified']);
這次我們不會使用到index,所以在建立時我們先就將他鎖起來。
那寫完路徑之後我們還需要一個入口進到我們的報名頁面,所以我們先到article的show去新增一個按鈕,讓別人可以清楚的知道如何報名。那我們就到blade中去新增我們的按鈕,resources\views\articles\show.blade.php
:
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 py-6">
<button type = "submit" class="px-3 py-1 rounded bg-gray-800 text-white hover:bg-gray-700">
<a href = "{{route('joiners.create', $article)}}"> 新增活動</a>
</button>
</div>
寫完入口後我們就要到controller中去迎接這位客人,那我們到app\Http\Controllers\JoinerController.php
:
/**
* Show the form for creating a new resource.
*/
public function create(Request $request)
{
$article = Article::find($request -> article);
return view('joiners.create', ['article' => $article]);
}
因為前面我們已經建過article的create了,所以知道這邊我們需要將我們的blade寫出來,那我們就先到resources\views
中新建一個資料夾然後放入我們的blade的檔案就開始寫程式吧。
<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-600 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.store') }}" method = "post">
@csrf
<div class="field my-2 ">
<lable for=""> {{__("生日")}} </lable>
<input type = "date" value="{{ old('birthday') }}" name = "birthday" class = "border-gray-300 p-2 mx-2">
</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" value="{{ old('ID_number') }}" name = "ID_number" class = "w-2/5 border-gray-300 p-2 mx-2">
</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" value="{{ old('phone') }}" name = "phone" class = "w-2/5 border-gray-300 p-2 mx-2 placeholder-gray-300" 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="{{ __('有甚麼話想對主辦方說的嗎...') }}">{{ old('note') }}</textarea>
</div>
</div>
<div class="flex mt-4 space-x-6 justify-center">
<div class="actions">
<button type = "submit" name="article_id" value="{{ $article -> id }}" 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>
接著我們到controller中去補足store的程式碼,完成store我們今天的工作也完成了。
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$content = $request->validate([
'note' => 'max:255',
'phone' => 'required|numeric:10',
'birthday' => 'required',
'ID_number' => 'required|min:10|max:10',
]);
auth()->user()->joinArticles()->syncWithoutDetaching([$request->article_id => $content]);
return redirect() -> route('dashboard');
}
這邊是不是有人發現,欸?怎麼和article之前的store有些不一樣?為甚麼有用到syncWithoutDetaching
這又是甚麼?
這是專門用來儲存多對多表格的方式,其實他總共有四種:attach、detach、sync、syncWithoutDetaching。
我們來一一了解他是什麼吧:
attach
他的用法是直接插入一筆新的資料,並不會去檢查這筆資料是否曾經存在。
arrary=[1,2,3]
attach([3,4,5])
=> arrary=[1,2,3,3,4,5]
detach
負責的是多對多關係的刪除,他和attach一樣並不會檢查資料是否存在,如果有就會刪除,沒有也不會報錯。
arrary=[1,2,3]
detach([3,4,5])
=> arrary=[1,2]
sync
sync只會儲存當下array裡有的資料,原本存在資料庫裡的資料,如果不在array裡,便會被刪除。
arrary=[1,2,3]
sync([3,4,5])
=> arrary=[1,2,3]
syncWithoutDetaching
這個是我們比較常用的函式,sync會幫我們檢查有沒有重複的關聯,但是我們希望只更新原本不存在的關係。
array=[1,2,3]
syncWithoutDetaching([3,4,5])
=> array=[1,2,3,4,5]
那我們今天了解了如何新增一筆多對多的資料,並且瞭解了多對多是怎麼儲存的,大家看我們這樣輕輕鬆鬆地就介紹完多對多的儲存,我們當時可是哀號了好幾個晚上到白天,最後才發現用如此簡單的方法就可以將資料存入。雖然這看似簡簡單單的程式碼,卻是多對多不可或缺的用法,大家還是要花些時間去了解喔,那我們今天就先到這裡,我們明天要來學前端,我們明天見,掰掰!