在控制器中具有相同方法的laravel应用程序

时间:2018-11-12 08:54:26

标签: laravel controller

我有Laravel应用程序,并且在控制器内部,我在多个控制器中使用了具有相同结构的相同方法(大多数但不是全部)

如何重构这些控制器以获得更清晰的代码结构?

我可以使用基本控制器并扩展所有控制器吗,或者可以使用trait

更新:

我将Datatable用于大多数控制器,因此我在这些控制器中有destroyMultipleupdateStatus方法。并且所有控制器中的代码内容是如此相似(例如:只有名称中有更改),我很难在我拥有的每15个控制器中复制此方法(并且随着系统中其他控制器的增长)

这是我的控制器代码:

<?php

namespace App\Http\Controllers\Admin;

use App\Library\AdminLib;
use App\Library\Datatable;
use App\Project;
use App\ProjectImage;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Session;

class ProjectController extends Controller {
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index () {
        return view("admin.projects.index");
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create () {
        $token = AdminLib::setUploadSession();

        return view("admin.projects.create" , compact('token'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store ( Request $request ) {
        $this->validate($request , [
            'title' => 'required' ,
            'alt'   => 'required|unique:projects' ,
        ]);

        $project         = new Project($request->only([
                                                          'image' ,
                                                          //its image file
                                                          'alt' ,
                                                          'title' ,
                                                          'description' ,
                                                          'meta_keywords' ,
                                                          'meta_description' ,
                                                      ]));
        $project->active = AdminLib::fixSwitch('active');
        $project->save();
        //save images that uploaded ajax ( relate them to this project )
        $token = AdminLib::getUploadSession();
        $images = ProjectImage::with([])
                              ->where('token' , $token)->get();
        $project->projectImages()
                ->saveMany($images);
        #

        $project->projectVideos()
                ->createMany(AdminLib::filterUrl($request->get('videos')));
        return redirect(route('admin.projects.index'))->with('success' , 'Information has been added');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Project $project
     * @return \Illuminate\Http\Response
     */
    public function edit ( Project $project ) {
        $token = AdminLib::setUploadSession();
        return view("admin.projects.edit" , compact('project' , 'token'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \App\Project             $project
     * @return \Illuminate\Http\Response
     */
    public function update ( Request $request , Project $project ) {
        $this->validate($request , [
            'title' => 'required' ,
            'alt'   => 'required' ,
        ]);
        $project->fill($request->only([
                                    'image' ,
                                    //its image file
                                    'alt' ,
                                    'title' ,
                                    'alt' ,
                                    'description' ,
                                    'meta_keywords' ,
                                    'meta_description' ,
                                ]));
        $project->active = AdminLib::fixSwitch('active');
        $project->save();

        //save images that uploaded ajax ( relate them to this project )
        $token = AdminLib::getUploadSession();
        $images = ProjectImage::with([])
                              ->where('token' , $token)->get();
        $project->projectImages()
                ->saveMany($images);
        //save video
        $project->projectVideos()
                ->delete();
        $project->projectVideos()
                ->createMany(AdminLib::filterUrl($request->get('videos')));

        return redirect(route('admin.projects.index'))->with('success' , 'Information has been updated');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param \App\Project $project
     * @return array
     * @throws \Exception
     */
    public function destroy ( Project $project ) {
        $ok = $project->delete();

        return compact('ok');
    }

    public function destroyMultiple () {

        $count = Project::with([])
                        ->whereIn('id' , \request('id_list'))
                        ->delete();
        $ok    = true;

        return compact('count' , 'ok');
    }

    public function updateStatus () {
        //some code to update status
    }

    public function datatable ( Request $request ) {
        $datatable = new Datatable();
        $response  = $datatable->setRequest($request)
                               ->setQuery(Project::with([]))
                               ->generalSearch(function ( Builder $query , $search ) {
                                   return $query->where('title' , 'like' , "%$search%")
                                                ->orWhere('id'  , "%$search%");
                               })
                               ->manipulateData(function ( Project $record ) {
                                   $record->action  = [
                                       //todo fix route
                                       'edit'    => route('admin.projects.edit' , $record->id) ,
                                       'destroy' => route('admin.projects.destroy' , $record->id) ,
                                   ];
                                   //todo use model to decorate this
                                   $record->created = "{$record->created_at->toFormattedDateString()} - {$record->created_at->toTimeString()}";

                                   return $record;
                               })
                               ->getResponse();

        return $response;
    }
}

2 个答案:

答案 0 :(得分:1)

如果您遵循REST,那么您的控制器应该看起来一样,并且在这种情况下继承并不是真正有用的,因为使用-r标志生成宁静的控制器将始终为您提供所需的所有方法。

答案 1 :(得分:0)

所有数据库逻辑应由模型负责。如果您有多个销毁和更新调用,最好从基础模型扩展所有模型,并使用Eloquent query scopes在基础模型中实现这两种方法。

Laravel的作者泰勒·奥特威尔(Taylor Otwell):

  

如果我从PHP中学到的一件事是控制器应该   没做什么。那些东西存在于这个空灵的飞机上,就像这样   朦胧的雾,什么都不做,将东西传给某个领域   抽象服务层

尽管他在同一个演讲中也提到很多情况都取决于用例,而以上是理想的情况。