2017-11-25 1 views
0

저는 Laravel에 비교적 익숙하며 내 프로젝트에서 'Ownable'Eloquent 객체를 처리하기위한 미들웨어와 정책을 만들었습니다. 기본 클래스를 사용한 Laravel 의존성 삽입

내가이이 특성을 사용했다 :

trait Ownable 
{ 

    public function user(){ 
     return $this->belongsTo(User::class, 'created_by'); 
    } 
} 

내 정책에서 나는 단순히 이렇게 :

class RightPolicy 
{ 
    use HandlesAuthorization; 

    public function update(User $user, Ownable $ownable) 
    { 
     return $ownable->created_by == $user->id; 
    } 
} 

그리고 내 컨트롤러에서 올바른 행동에 할당 내 미들웨어 :

class CheckRights 
{ 
    public function __construct(Route $route, Ownable $object) { 
     $this->route = $route; 
     $this->object = $object; 
    } 

    public function handle($request, Closure $next) 
    { 
     // @TODO handle request 
    } 
} 

그럼 Ownable 특성을 사용하여 클래스를 만들었습니다 :

Target [App\Ownable] is not instantiable while building App\Http\Middleware\CheckRights

아마 사용 (종속성 인젝터가 올바른 클래스의 인스턴스를 알릴 수있는 방법이 있나요 :이 구조 프로젝트를 실행하려고하면

class Thread extends Model 
{ 
    use Ownable; 
} 

그러나, Laravel의 종속 인젝터는 오류가 trhows 경로 또는 뭔가 다른)?

그렇지 않은 경우, 올바른 클래스가 인스턴스화되었는지 확인하기 위해 종속성 인젝터가없는 다른 편리한 방법이 있습니까?

+0

특성은 정의에 의해 인스턴스화 할 수 없습니다. 나는 여기에 특성이 필요하다고 생각하지 않는다. 클래스와 확장에 관한 것이 더 많다. –

+0

나는 다형성을 이유로 여기에서 형질을 사용하고 있음을 이해한다. 스레드는 Ownable이지만 주석이 가능하지만 ForumRule은 소유 할 수 없지만 주석이 가능합니다 (예 :). 이것이 내가 이런 유형의 구조를 선택한 이유입니다. @VincentDecaux – Joas

+0

특성 사용 결과는 항상 올바른 클래스로 작성할 수 있습니다. Laravel은 그 특성에 자동 해상도를 적용 할 때 작동하지 않는 init를 시도합니다. 그래서 당신이 원하는 지점으로 가고 싶다면 당신의 방법은 여기에 특성을 사용하는 대신 클래스로 전환하는 것입니다. –

답변

0

AppServiceProvider에서 app :: bind 메서드를 사용하여이 문제를 해결했습니다.

서비스 제공 업체의 등록 방법에서는 App \ Ownable 인터페이스를 라우터에 전달 된 주입 된 모든 Eloquent 객체를 반복하여 순환시키는 함수를 바인딩했습니다. 내가 올바른 typehinting위한 인터페이스와 소유 가능한 특성을 결합하여 다음 Binding

타 웹 사이트에 공개 토론에 제안, : 내 미들웨어에 그런

class Thread extends Model implements \App\Interfaces\Ownable 
{ 
    use Ownable; 
} 

에 대해

namespace App\Providers; 

use App\Ownable; 
use Illuminate\Support\Facades\Route; 
use Illuminate\Support\ServiceProvider; 
use Illuminate\Support\Facades\Schema; 

class AppServiceProvider extends ServiceProvider 
{ 
    public function boot() 
    { 
     Schema::defaultStringLength(191); 
    } 

    public function register() 
    { 
     // Binding ownable trait/interface for correctly handling policy 
     $this->app->bind('App\Ownable', function() { 
      // Get all parameters passed to the current route 
      $array = Route::getCurrentRoute()->parameters; 

      $return = NULL; 
      foreach ($array as $object){ 
       if ($object instanceof Ownable){ 
        // Fetch the last ownable instance found passed to the route 
        $return = $object; 
       } 
      } 

      // return it 
      return $return; 
     }); 
    } 
} 

자세히보기 생성자 나는 소유 매개 변수를 선택적으로 만들었습니다 (상점 또는 생성 작업이 호출되고 객체가 주어지지 않을 때). 작업 이름과 객체가 주어진 경우 내 요청을 처리했습니다.

class CheckRights 
{ 
    public function __construct(Route $route, Ownable $object = null) { 
     $this->route = $route; 
     $this->object = $object; 
    } 

    public function handle($request, Closure $next) 
    { 
     // Get the controller's action name 
     $action = $this->route->getActionName(); 
     $action = substr($action, strpos($action, '@') + 1); 

     // Check if an object is given in the request 
     if ($action != 'store' && $action != 'create' && isset($this->object)){ 
      // Check if gate allows user to update/delete object 
      if ($request->user()->can($action, $this->object)){ 
       return $next($request); 
      } 
     }elseif($action == 'store' || $action == 'create'){ 
      // Check if gate allows user to create object 
      if ($request->user()->can($action, Ownable::class)){ 
       return $next($request); 
      } 
     } 

     return back(); 
    } 
}