数据库课程作业笔记 - 编写控制器
控制器
参考文档
这里涉及比较多的知识,但我们并不用到全部,需要的时候有疑惑可以参考文档,阅读文档可以帮助我们理解整个流程。
创建资源控制器
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 一下那就写得规范一点吧。
其他的控制器都有类似的逻辑,只是界面传参和连表不同,完成了控制器我们的作业要求也就完成咯~
本作品采用《CC 协议》,转载必须注明作者和本文链接