控制器
參考文件
這裡涉及比較多的知識,但我們並不用到全部,需要的時候有疑惑可以參考文件,閱讀文件可以幫助我們理解整個流程。
建立資源控制器
php artisan make:controller PurchaseController --resource
在 php artisan make:controller
後面加 --resource
引數可以建立資源路由,對於我們在 Route 裡面的 resource 所建立的路由,下面我們完成這個路由。
這裡以 購買記錄 舉例,其他控制器擁有類似結構
<?php
namespace App\Http\Controllers;
use App\Http\Requests\PurchaseRequest;
use App\Models\Customer;
use App\Models\Employee;
use App\Models\Product;
use App\Models\Purchase;
use Illuminate\Http\Request;
class PurchaseController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$relations = [
'customer:'.Customer::ID.','.Customer::NAME,
'employee:'.Employee::ID.','.Employee::NAME,
'product:'.Product::ID.','.Product::NAME
];
$data = Purchase::with($relations)->get();
foreach ($data as $purchase) {
$purchase[Purchase::CID] = $purchase['customer'][Customer::NAME];
$purchase[Purchase::EID] = $purchase['employee'][Employee::NAME];
$purchase[Purchase::PID] = $purchase['product'][Product::NAME];
unset($purchase['customer']);
unset($purchase['employee']);
unset($purchase['product']);
}
return view('homework2._list',[
'title'=>'購買記錄 purchase',
'columns' => [
Purchase::CID => '客戶',
Purchase::EID => '員工',
Purchase::PID => '產品',
Purchase::QTY => '數量',
Purchase::PTIME => '購買時間',
Purchase::TOTAL_PRICE => '總價',
Purchase::CREATED_AT => '建立時間',
Purchase::UPDATED_AT => '修改時間',
],
'data' => $data->toArray(),
'create' => 'purchase.create',
'edit' => 'purchase.edit',
'delete' => 'purchase.destroy'
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$customers = Customer::all([Customer::ID.' as id', Customer::NAME.' as text']);
$employees = Employee::all([Employee::ID.' as id', Employee::NAME.' as text']);
$products = Product::all([Product::ID.' as id', Product::NAME.' as text']);
return view('homework2.edit_purchase',[
'customers' => $customers,
'employees' => $employees,
'products' => $products
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(PurchaseRequest $request)
{
$purchase = new Purchase($request->validated());
$purchase->save();
return redirect()->to(route('purchase.index'))->with('success', '新增成功');
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit(Purchase $purchase)
{
$customers = Customer::all([Customer::ID.' as id', Customer::NAME.' as text']);
$employees = Employee::all([Employee::ID.' as id', Employee::NAME.' as text']);
$products = Product::all([Product::ID.' as id', Product::NAME.' as text']);
$data = $purchase->toArray();
$data['customers'] = $customers;
$data['employees'] = $employees;
$data['products'] = $products;
return view('homework2.edit_purchase',$data);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(PurchaseRequest $request, Purchase $purchase)
{
$purchase->update($request->validated());
return redirect()->back()->with('success', '更新成功');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Purchase $purchase)
{
try {
$purchase->delete();
} catch (\Exception $exception) {
return redirect()->back()->with('danger',$exception->getMessage());
}
return redirect()->back()->with('success', '刪除成功');
}
}
分析解釋 - 列表
先看看購買記錄列表 index 方法
public function index()
{
$relations = [
'customer:'.Customer::ID.','.Customer::NAME,
'employee:'.Employee::ID.','.Employee::NAME,
'product:'.Product::ID.','.Product::NAME
];
$data = Purchase::with($relations)->get();
foreach ($data as $purchase) {
$purchase[Purchase::CID] = $purchase['customer'][Customer::NAME];
$purchase[Purchase::EID] = $purchase['employee'][Employee::NAME];
$purchase[Purchase::PID] = $purchase['product'][Product::NAME];
unset($purchase['customer']);
unset($purchase['employee']);
unset($purchase['product']);
}
return view('homework2._list',[
'title'=>'購買記錄 purchase',
'columns' => [
Purchase::CID => '客戶',
Purchase::EID => '員工',
Purchase::PID => '產品',
Purchase::QTY => '數量',
Purchase::PTIME => '購買時間',
Purchase::TOTAL_PRICE => '總價',
Purchase::CREATED_AT => '建立時間',
Purchase::UPDATED_AT => '修改時間',
],
'data' => $data->toArray(),
'create' => 'purchase.create',
'edit' => 'purchase.edit',
'delete' => 'purchase.destroy'
]);
}
這裡的 Purchase::with($relations)->get();
中的 with
表示使用關係,這個關係定義在模型當中,在 Purchase 模型中定義瞭如上三個關係,使用 customer:id,cname
這樣的格式可以查出對於外來鍵的customer
資料項中的id
和cname
foreach ($data as $purchase) {
$purchase[Purchase::CID] = $purchase['customer'][Customer::NAME];
$purchase[Purchase::EID] = $purchase['employee'][Employee::NAME];
$purchase[Purchase::PID] = $purchase['product'][Product::NAME];
unset($purchase['customer']);
unset($purchase['employee']);
unset($purchase['product']);
}
這裡將原來的外來鍵換成名稱並去掉對應項
return view('homework2._list',[
'title'=>'購買記錄 purchase',
'columns' => [
Purchase::CID => '客戶',
Purchase::EID => '員工',
Purchase::PID => '產品',
Purchase::QTY => '數量',
Purchase::PTIME => '購買時間',
Purchase::TOTAL_PRICE => '總價',
Purchase::CREATED_AT => '建立時間',
Purchase::UPDATED_AT => '修改時間',
],
'data' => $data->toArray(),
'create' => 'purchase.create',
'edit' => 'purchase.edit',
'delete' => 'purchase.destroy'
]);
這裡 view()
返回 resource\views 中的模板檔案, homework2._list
是我們在 homework2 資料夾下寫的 blade 模板檔案,需要傳遞的引數在後面傳遞對應的陣列,這裡傳遞了顯示的名稱,列表名稱,資料,跳轉的路由,這樣就可以完成我們的列表頁面了。
分析解釋 - 建立介面和修改介面
建立新的購買記錄 create 方法
public function create()
{
$customers = Customer::all([Customer::ID.' as id', Customer::NAME.' as text']);
$employees = Employee::all([Employee::ID.' as id', Employee::NAME.' as text']);
$products = Product::all([Product::ID.' as id', Product::NAME.' as text']);
return view('homework2.edit_purchase',[
'customers' => $customers,
'employees' => $employees,
'products' => $products
]);
}
修改比建立多了一個引數 Purchase $purchase
這個引數也是通過自動依賴注入完成的,由於在路由我們定義了一個 id 引數,這裡 Laravel 通過這個引數可以自動為我們例項化這個模型物件,這裡會自動找出對應的 id 模型,下面呼叫 to->Array()
方法將模型轉成關係陣列傳遞給試圖。
public function edit(Purchase $purchase)
{
$customers = Customer::all([Customer::ID.' as id', Customer::NAME.' as text']);
$employees = Employee::all([Employee::ID.' as id', Employee::NAME.' as text']);
$products = Product::all([Product::ID.' as id', Product::NAME.' as text']);
$data = $purchase->toArray();
$data['customers'] = $customers;
$data['employees'] = $employees;
$data['products'] = $products;
return view('homework2.edit_purchase',$data);
}
由於需要完成下拉選單的操作,所以有三個下拉選單則從三個表中選取 ID
和 NAME
作為下拉選單的對應項,這裡用 [Customer::ID.' as id', Customer::NAME.' as text']
來將對應的列重新命名,這是使用了原生語句的 as
功能,all
方法是靜態方法,可以快速構造出 mysql 查詢語句查詢全部的資料,裡面傳入需要查詢的列作為 select
引數,想學習跟多關於查詢構造器則可以參考相關文件。
下面的 view 與上面用法一樣,由於設定了三個下拉框所以需要傳入三個屬性。
分析解釋 - 建立與更新
建立和前面的傳參不同,建立需要傳入引數,所以需要經過前面的請求表單驗證。
public function store(PurchaseRequest $request)
{
$purchase = new Purchase($request->validated());
$purchase->save();
return redirect()->to(route('purchase.index'))->with('success', '新增成功');
}
這裡傳入引數使用 PurchasesRequest $request
原理是自動依賴注入,可以參考文件服務容器,簡單的說就是在呼叫方法時 Laravel 會自動呼叫設定好的例項化方法去例項化這個物件,在例項化的過程中會呼叫我們設定在 PurchaseRequest 中的 rule 方法校驗。這種自動依賴注入幫我們省去了很多例項化程式碼,使得我們的控制器寫的如此簡潔。
用 $request->validated()
可以獲取通過驗證的引數例項化模型 Purchase 並使用 save
方法儲存到資料庫,用 redirect()->to(route('purchase.index'))->with('success', '新增成功')
來返回一個重定向回覆到 route('purchase.index')
這個路由,這個 route()
方法幫我們從路由名中獲取 url,這個路由嗎由前面路由那一章節定義的 Route::resource()
自動定義的資源路由名稱,用 with
來帶上 Session 這樣就可以觸發我們訊息模板 _message.blade.php
來顯示新建成功提示。
public function update(PurchaseRequest $request, Purchase $purchase)
{
$purchase->update($request->validated());
return redirect()->back()->with('success', '更新成功');
}
更新與建立的唯一區別就是這個模型由引數的 id 來自動注入,之後幾乎一樣。
分析解釋 - 刪除
public function destroy(Purchase $purchase)
{
try {
$purchase->delete();
} catch (\Exception $exception) {
return redirect()->back()->with('danger',$exception->getMessage());
}
return redirect()->back()->with('success', '刪除成功');
}
刪除也通過依賴注入,所以依賴注入實在非常方便。這裡本來可以一句話搞定,但 IDE 提示最好 try catch 一下那就寫得規範一點吧。
其他的控制器都有類似的邏輯,只是介面傳參和連表不同,完成了控制器我們的作業要求也就完成咯~