扩展资源控制器

时间:2014-03-21 13:13:15

标签: laravel laravel-4

我正在以某种方式做我想做的事情,而我正在寻找替代方案或更好的方法。 我在我的应用程序中使用资源控制器。另外我在几个型号中使用softdelete,所以我的路线如下:

Route::get('users/deleted', array('uses' => 'UserController@trash'));
Route::put('users/{id}/restore', array('uses' => 'UserController@restore'));
Route::resource('users', 'UserController');

第一条路线是显示已删除的对象。 第二个允许我恢复这些删除的元素。 第三种映射传统方法(创建,编辑,更新等)。

我有几个控制器的工作方式完全相同,我想知道是否有任何方法可以告诉laravel默认情况下使用这两种方法(垃圾和删除),而不需要额外的两行。

有可能吗?或者提供一个更好的方式,我正在做什么? (抱歉英语不好)

3 个答案:

答案 0 :(得分:7)

保持简单和干燥。

您可以扩展路由器并替换app/config/app.php文件中的路由外观,但似乎需要做很多工作才能获得更多收益,但不要忘记您的路由文件是PHP脚本而您可以做的事情如下:

$routes = [
    ['users' => 'UserController'],
    ['posts' => 'PostController'],
];

foreach ($routes as $key => $controller)
{
    Route::get("$key/deleted", array('uses' => "$controller@trash"));

    Route::put("$key/{id}/restore", array('uses' => "$controller@restore"));

    Route::resource($key, $controller);
}

扩展路由器

要扩展路由器,您需要创建3个类:

路由器已扩展,您可以在其中添加新方法:

<?php namespace App\Routing;

class ExtendedRouter extends \Illuminate\Routing\Router {

    protected $resourceDefaults = array(
                'index', 
                'create', 
                'store', 
                'show', 
                'edit', 
                'update', 
                'destroy', 
                'deleted',
                'restore',
    );

    protected function addResourceDeleted($name, $base, $controller)
    {
        $uri = $this->getResourceUri($name).'/deleted';

        return $this->get($uri, $this->getResourceAction($name, $controller, 'deleted'));
    }

    protected function addResourceRestore($name, $base, $controller)
    {
        $uri = $this->getResourceUri($name).'/{resource}/restore';

        return $this->get($uri, $this->getResourceAction($name, $controller, 'restore'));
    }

}

服务提供商,使用Laravel使用的相同IoC标识符启动新路由器(&#39;路由器&#39;):

<?php namespace App\Routing;

use Illuminate\Support\ServiceProvider;

class ExtendedRouterServiceProvider extends ServiceProvider {

    protected $defer = true;

    public function register()
    {
        $this->app['router'] = $this->app->share(function() { return new ExtendedRouter($this->app); });
    }

    public function provides()
    {
        return array('router');
    }

}

和Facade,取代Laravel的一个

<?php namespace App\Facades;

use Illuminate\Support\Facades\Facade as IlluminateFacade;

class ExtendedRouteFacade extends IlluminateFacade {

    public static function is($name)
    {
        return static::$app['router']->currentRouteNamed($name);
    }

    public static function uses($action)
    {
        return static::$app['router']->currentRouteUses($action);
    }

    protected static function getFacadeAccessor() { return 'router'; }

}

然后,您需要将您的服务提供商和Facade添加到您的app/config/app.php文件中,对Laravel原始文件进行评论。

答案 1 :(得分:1)

我使用路由模型绑定。

我这样做。

<?php

namespace App\Http\Router;

use Illuminate\Support\Facades\Route;
use Illuminate\Routing\Router;

class CustomRouter extends Router
{
    public function customResource($routeName, $controllerPath, $routeBindName = null, $routeBindModel = null) {
        $routeBindName = $routeBindName ?? $routeName;

        $routeBindNameTrashed = "{$routeBindName}_trashed";

        if($routeBindModel && $routeBindName) {
            Route::model($routeBindName, $routeBindModel);
            Route::bind($routeBindNameTrashed, function($modelId) use ($routeBindModel) {
                return app($routeBindModel)->newQuery()->onlyTrashed()->findOrFail($modelId);
            });
        }

        Route::put("$routeName/{{$routeBindNameTrashed}}/restore", "{$controllerPath}@restore")->name("{$routeName}.restore");
        Route::delete("$routeName/{{$routeBindNameTrashed}}/force", "{$controllerPath}@forceDelete")->name("{$routeName}.force-delete");
        Route::resource($routeName, $controllerPath);
    }
}

Alter bootstrap / app.php

$app->singleton(
    'router', 
    App\Http\Router\CustomRouter::class
);

然后的用法:

Route::customResource('projects', 'ProjectsController', 'project', \App\Models\Project::class);

路线:列表 router:list laravel extends resource controllers

答案 2 :(得分:0)

像魅力一样工作

$routes = [
    'posts' => 'PostController',
    'posts.comments' => 'PostCommentController',
];

foreach ($routes as $key => $controller)
{
    Route::get("$key/deleted", array('uses' => "$controller@trash"));

    Route::put("$key/{id}/restore", array('uses' => "$controller@restore"));

    Route::resource($key, $controller);
}