数据库课程作业笔记 - 编写控制器

控制器

参考文档

这里涉及比较多的知识,但我们并不用到全部,需要的时候有疑惑可以参考文档,阅读文档可以帮助我们理解整个流程。

创建资源控制器

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数据项中的idcname

 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);
    }

由于需要完成下拉列表的操作,所以有三个下拉列表则从三个表中选取 IDNAME 作为下拉列表的对应项,这里用 [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 协议》,转载必须注明作者和本文链接
MARTINPOTTER
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!