将控制器功能映射到Laravel中的数据库记录中

将控制器功能映射到Laravel中的数据库记录中,laravel,laravel-artisan,Laravel,Laravel Artisan,我尝试在我的Laravel应用程序中实施一系列批准方法 假设我有一个带有标准REST路由的标准CRUD控制器 [URL]/产品 在控制器中,我有3个函数:索引、存储、更新 我希望存储和更新之前会发生某种情况,类似于: if (fucntion requires chain of approval) { if (auth()->user !== one of the approvers){ email all approvers; return 201

我尝试在我的Laravel应用程序中实施一系列批准方法

假设我有一个带有标准REST路由的标准CRUD控制器

[URL]/产品

在控制器中,我有3个函数:索引、存储、更新

我希望存储和更新之前会发生某种情况,类似于:

if (fucntion requires chain of approval) {
    if (auth()->user !== one of the approvers){
        email all approvers;
        return 201 "pending approval";
    }
}

// the logged in user is allowed to execute the function
rest of the code...
我在这里遇到了一些问题:

在Laravel内部,我能想到的唯一一件可能与此类似的事情是$this->authorize函数,但我不认为它是用来这样使用的,它是用来授权还是不授权,不是用于201代码,使用它意味着用201终止,它不正确

我想让管理员控制哪些功能需要批准,因为我不想将控制器功能与包含所有功能列表的播种器一起维护,我正在考虑创建一个artisan命令,以便在生产之前运行,并将所有功能映射到将用作模型和所有流程将在功能和审批人之间使用适当的多对多关系,但我不知道如何使用artisan命令映射功能,我也不知道这是否是正确的方法

我希望避免在所有可能需要批准的函数中编写特定代码,甚至不知道如何以及是否可能

函数的返回应该返回特定模型的JsonResource,例如ProductResource,当我需要批准时应该返回什么?只是为了模拟一个状态为挂起的正确响应


感谢所有愿意给我一些指导的人。

你可以做类似于下面的事情。。。只有一个类定义如何处理每个用户类型甚至权限

public function index(IndexRequest $request) // verify that use is authorized to do this action 
{
  $response = (new MyJobDirector)->handle(Auth::user());

  .. handle response
}
MyJobDirector类

class MyJobDirector
{
  const STRATEGY = [
    'user' => 'userHandler',
    'manager' => 'managerHandler',
  ];

  public function handle(User $user): array
  {
    return $this->{static::STRATEGY[$user->role]}();
  }

  protected function userHandler(): array 
  {
    event(EmailApprovers::class);

    return [
      'code' => 201,
      'response' => 'pending approval',
    ];
  }
}
通过为每个处理程序定义一个单独的类,并为每个类应该返回的状态和响应指定常量,可以使它变得更加复杂

class User extends BaseJobHandle
{
  const CODE = 201;
  const RESPONSE = 'pending approval';
}
关于函数的返回应该返回特定模型的JsonResource,例如ProductResource,当我需要批准时应该返回什么?只是为了模拟一个状态为挂起的正确响应


您可以有一个ProductResource类,在该类中,您可以根据用例决定返回哪个特定资源。这完全取决于您需要返回的数据。

您对问题2有什么建议吗?我不知道您为什么要执行第2点。也很难理解。每次用户访问某个功能时,我都需要检查该功能是否需要批准,我想要控制关系的地方是DB,但我没有任何东西可以在实际控制器功能和批准组之间映射,否则,您将如何将实际的控制器和方法映射到某个组?您可以通过中间件来实现。对于每个路由/路由组,您可以定义要使用的中间件。您还可以将参数传递给中间件。因此,分配一个处理权限的中间件,并传递您希望用户拥有的权限。我知道如何处理权限,一旦我已经拥有了DB,以及我知道如何处理它的所有方法的列表,我的问题是,如果一个新的编码者在其中一个控制器中编写了一个新方法,在DB中就不会有这个方法的表示,除非一些自动或手动(最好是自动)将新方法插入DB,我正在寻找一种优雅的方式来列出数据库中的所有控制器方法
abstract class BaseJobHandler
{
  const CODE;
  const RESPONSE;

  public function handle(): array 
  {
    $this->additionalProcesses();

    return [
      'code' => static::CODE,
      'response' => static::RESPONSE,
    ];
  }

  protected function additionalProcesses(): void {}
}
class MyJobDirector
{
  const STRATEGY = [
    'user' => User::class,
    'manager' => Manager::class,
  ];

  public function handle(User $user): array
  {
    $class = static::STRATEGY[$user->role];

    return (new $class)->handle();
  }
}