2015-12-28 2 views
0

У меня есть несколько ресурсов в Laravel 5.1, которые представлены в моделях. Все модели имеют account_id и user_id. Существует сводная таблица user_account, которая представляет взаимосвязь между учетными записями и пользователями.Модели, контроллеры ресурсов и промежуточное ПО в Laravel 5.1

У меня есть маршруты в routes.php, которые являются контроллерами ресурсов, такими как route.asset.

Я ищу, чтобы создать одну Middleware для всех этих контроллеров, такой я могу сделать, прежде чем => [ «belongstoaccount»]

И в этом промежуточном слое следует проверить:

Пользователя принадлежит к счету в account.asset (в настоящее время я использую -> содержит() в контроллерах.)

Свойство account_id этого ресурса совпадает с идентификатором account->.

Я хочу создать одно промежуточное ПО для всех этих активов. Возможно ли это? Должен ли я искать в $ request для этой информации?

Спасибо за какие-либо указания,

Джоша

ответ

1

Это на самом деле не так уж сложно, но это требует немного установки для промежуточного слоя, чтобы быть в состоянии определить, какой ресурс загружаются. Это достигается с помощью Route-Model Binding

Примера ресурсных маршрутов:

Route::group(['middleware' => 'BelongsToAccount'], function() { 
    Route::resource('asset', 'AssetController'); 
    Route::resource('liability', 'LiabilityController'); 
}); 

Теперь нам нужно связать ресурсы в RouteServiceProvider, чтобы наши маршруты загрузят ресурсы:

/** 
    * Define your route model bindings, pattern filters, etc. 
    * 
    * @param \Illuminate\Routing\Router $router 
    * @return void 
    */ 
    public function boot(Router $router) 
    { 
     parent::boot($router); 
     // bound models 
     $router->model('asset', 'App\Asset'); 
     $router->model('liability', 'App\Liability'); 
    } 

Теперь перейдите к middleware's handle метод и свалка $request->route()->parameters();. Вы должны увидеть ресурс, указанный в списке параметров. С экземпляром ресурса, доступного в запросе, последний шаг, чтобы проверить и подтвердить против него в ПО промежуточного слоя:

<?php namespace App\Http\Middleware; 

use Closure; 
use Illuminate\Contracts\Auth\Guard; 
use Illuminate\Database\Eloquent\Model; 
use Illuminate\Contracts\Routing\Middleware; 
class BelongsToAccount implements Middleware { 
    /** 
    * The Guard implementation. 
    * 
    * @var Guard 
    */ 
    protected $auth; 
    /** 
    * Create a new filter instance. 
    * 
    * @param Guard $auth 
    * @return void 
    */ 
    public function __construct(Guard $auth) 
    { 
     $this->auth = $auth; 
    } 

    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * @return mixed 
    */ 
    public function handle($request, Closure $next) 
    { 
     // get the resource from the route 
     $resource = $this->getResource($request); 

     if (!empty($resource)) 
     { 
      if ($this->auth->user()->accountId == $resource->accountId) 
      { 
       return $next($request); 
      } 
     } 
    } 

    /** 
    * Get resource from route if it exists 
    * 
    * @param \Illuminate\Http\Request $request 
    * @return mixed 
    */ 
    public function getResource($request) 
    { 
     foreach ($request->route()->parameters() as $param) 
     { 
      if ($param instanceof Model) return $param; 
     } 

     return null; 
    } 
} 

Этот код выше не будет подключи и играй, вам, возможно, придется изменить именно как вы получаете значение accountId от вашего в настоящее время вошедшего в систему пользователя и т. д. Но суть того, что здесь происходит, - это дополнительный метод для поиска экземпляра Eloquent\Model. Как только он будет найден, он вернет этот ресурс, который будет использоваться промежуточным программным обеспечением, и предположим, что ресурс уже связан с идентификатором accountId.

Если вы хотите более тонкий контроль, я бы предложил переместить промежуточное программное обеспечение на __construct контроллера, чтобы более точно настроить действия контроллера, над которыми он работает. Однако вы можете это сделать и в файле маршрутов.

Надеюсь, это поможет!

Смежные вопросы