【问题标题】:Extend Resource Controllers扩展资源控制器
【发布时间】:2014-04-28 21:10:39
【问题描述】:

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

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

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

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

有可能吗?或者给我一个更好的方法? (抱歉英语不好)

【问题讨论】:

    标签: laravel laravel-4


    【解决方案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);
        }
    }
    
    

    修改 bootstrap/app.php

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

    然后用法:

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

    路线:列表

    【讨论】:

      【解决方案2】:

      像魅力一样工作

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

      【讨论】:

        【解决方案3】:

        保持简单和干燥。

        您可以在 app/config/app.php 文件中扩展路由器并替换 Route Facade,但似乎需要做很多工作却收效甚微,但不要忘记您的路由文件是一个 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 个类:

        Router 扩展,您将在其中添加新方法:

        <?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 标识符(“路由器”)启动新路由器:

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

        还有一个门面,用来代替 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'; }
        
        }
        

        然后你需要将你的 Service Provider 和 Facade 添加到你的 app/config/app.php 文件中,注释掉 Laravel 的原始文件。

        【讨论】:

        • 使用 Laravel 4.1 ServiceProvider 需要注册到 Illuminate\Events\Dispatcher 而不是 app。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-05
        • 2015-01-22
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多