:::
主內容區域
14. 修改測驗
一、修改樣板,加入編輯按鈕
-
修改原來的
/專案/resources/views/exam/show.blade.php樣板,加入編輯按鈕:<h1 class="text-center"> {{$exam->title}} @can('建立測驗') <a href="{{route('exam.edit', $exam->id)}}" class="btn btn-warning">編輯</a> @endcan </h1> - 我們必須根據不同權限顯示不同功能,老師和學生在進入測驗的畫面時,應該要看到不同功能,老師應該是要進行題目管理,學生則是進行測驗。利用
@can()就可以判斷不同身份。 - 詳情請看:https://github.com/laravel-backpack/permissionmanager
二、修改路由
- 修改路由
/專案/routes/web.php加入edit的路由,{exam}放在前後其實都沒關係。Route::get('/exam/{exam}/edit', 'ExamController@edit')->name('exam.edit');
三、修改控制器(用同一個視圖)
-
修改的界面主要就是讀出原始內容,然後塞到原來的建立標單裡,也就是套用到
exam/create.blade.php的表單中。這裡我們不另外做edit.blade.php用來編輯的視圖,因為編輯和建立的視圖其實90%以上都一樣,弄個兩套維護起來比較不易(容易改了A卻忘了B),所以,我們來看一下用同一個視圖,需要注意哪些事?-
建立的http動詞是
post,修改則是patch(如此,會自動加上CSRF保護,避免跨站攻擊) -
建立的表單
action是/exam,修改則是/exam/編號 -
建立時,啟用欄位(enable)預設值為1,修改時,則是視實際情況
-
-
所以,根據以上,我們在控制器中
/專案/app/Http/Controllers/ExamController.php,先加入edit的方法:public function edit(Exam $exam) { return view('exam.create', compact('exam')); }-
$exam是一筆完整Exam資料,$exam->id就是該資料的編號
-
-
最後,修改
/專案/resources/views/exam/create.blade.php樣板:@extends('layouts.app') @section('content') <h1>{{ __('Create Exam') }}</h1> @can('建立測驗') @if(isset($exam)) {{ bs()->openForm('patch', "/exam/{$exam->id}" , [ 'model' => $exam]) }} @else {{ bs()->openForm('post', '/exam') }} @endif {{ bs()->formGroup() ->label('測驗標題', false, 'text-sm-right') ->control(bs()->text('title')->placeholder('請填入測驗標題')) ->showAsRow() }} {{ bs()->formGroup() ->label('測驗狀態', false, 'text-sm-right') ->control(bs()->radioGroup('enable', [1 => '啟用', 0 => '關閉']) ->selectedOption(isset($exam)?$exam->enable:1) ->inline()) ->showAsRow() }} {{ bs()->hidden('user_id', Auth::id()) }} {{ bs()->formGroup() ->label('') ->control(bs()->submit('建立測驗')) ->showAsRow() }} {{ bs()->closeForm() }} @if (count($errors) > 0) @component('bs::alert', ['type' => 'danger']) <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> @endcomponent @endif @else @component('bs::alert', ['type' => 'danger']) @slot('heading') 無建立測驗的權限 @endslot @endcomponent @endcan @endsection- 第5行的地方,我們判斷有無傳進 $exam 物件,來決定是要新增還是修改?
- 第6行的地方,當有測驗編號,那就是修改,http動詞我們改用
patch。action路徑也不同,加入測驗編號$exam->id。此外,多了['model' => $exam],也就是此表單要套用預設值。 - 18行用三元一次寫法,判斷有物件時才使用物件值,沒有就給1
- 看起來像這樣:

- 最後,只要完成「更新」部份的功能即可。
三、讓被關閉的測驗也能顯示出來
- 在修改的過程中發現,被關閉的測驗將不會被列出,故也無法修改,所以,我們需要調整一下,改成若是有「建立測驗」權限者,就可以看到被關閉測驗,若沒有,則不秀出。
- 所以,我們先修改控制器
/專案/app/Http/Controllers/ExamController.php,編輯index的方法:public function index() { $user = Auth::user(); if ($user and $user->can('建立測驗')) { $exams = Exam::orderBy('created_at', 'desc') ->paginate(3); } else { $exams = Exam::where('enable', 1) ->orderBy('created_at', 'desc') ->paginate(2); } return view('exam.index', compact('exams')); }-
主要是先取得使用者資料,此時,上方需告知要使用
Illuminate\Support\Facades\Auth才行use Illuminate\Support\Facades\Auth; -
接著判斷有無$user物件(沒登入者不會有),若有,判斷有無權限。
-
有權限者就不加上
where('enable', 1)這個條件(顯示數也可以調多一點)
-
-
接著修改
\專案\resources\views\exam\index.blade.php,加入判斷,若$exam->enable不等於1,就顯示一個關閉的徽章@extends('layouts.app') @section('content') <h1>測驗一覽<small>(共 {{$exams->total()}} 筆資料)</small></h1> <ul class="list-group"> @forelse ($exams as $exam) <li class="list-group-item"> @if($exam->enable!=1) {{ bs()->badge()->text('關閉') }} @endif {{$exam->created_at->format("Y年m月d日") }} - <a href="exam/{{$exam->id}}"> {{$exam->title}} </a> </li> @empty <li class="list-group-item">尚無任何測驗</li> @endforelse </ul> <div class="my-3"> {{ $exams->links() }} </div> @endsection -
看起來就像這樣:

13-1 建立Seeder快速填充資料
