如何(正确)使用具有依赖关系的表单请求 + 策略 + 资源路由?
Posted
技术标签:
【中文标题】如何(正确)使用具有依赖关系的表单请求 + 策略 + 资源路由?【英文标题】:How to (properly) use form requests + policies + resource routes with dependencies? 【发布时间】:2018-04-22 08:51:56 【问题描述】:我的用例是用户是/拥有一家拥有员工的公司。
使用表单控制器和模型策略我试图找出最好/正确的方法应该是什么。
路线:
Route::resource('company', \App\Http\Controllers\Api\v1\CompanyController::class);
Route::resource('employee', \App\Http\Controllers\Api\v1\EmployeeController::class);
员工商店要求:
namespace App\Http\Requests;
use App\Models\Employee;
use Illuminate\Foundation\Http\FormRequest;
class EmployeeStoreRequest extends FormRequest
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
return $this->user()->can('create', Employee::class);
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
return [
'company_id' => 'required|integer|exists:companies,id'
];
员工政策:
...
/**
* Determine whether the user can create employees.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
return $user->can('update', Company::find(
app('request')->get('company_id')
));
...
因此,我对策略如何检查用户是否可以编辑员工所属的公司并不特别满意,因为这只发生在 http 上,对于控制台/测试,这会中断。
那么添加这个检查最合乎逻辑的方法是在表单请求的 authorize() 函数中,但是你正在检查策略之外的权限,这听起来不合逻辑。
简而言之,问题是:您如何以及为什么要使用表单请求和模型策略来做到这一点?
【问题讨论】:
【参考方案1】:只需要在EmployeePolicy@create
方法中添加公司的id
,就可以在http之外使用了
EmployeePolicy
public function create(User $user, $companyId)
return $user->can('update', $companyId);
EmployeeStoreRequest
public function authorize()
return $this->user()->can('create', Employee::class, $this->request->get('company_id'));
您可以在 http 之外使用 tinker
对其进行测试
php artisan tinker
$user = User::find(2); // or whatever user you want to test with
$user->can('create', Employee::class, 3); // 3 = company_id
【讨论】:
你确定这条线是正确的吗?return $user->can('update', $companyId);
。就像在这种情况下 Laravel 应该如何知道检查 CompanyPolicy
一样?我觉得return $user->can('update', Company::class, $companyId);
更合适,就像你在EmployeStoreRequest
中所做的那样以上是关于如何(正确)使用具有依赖关系的表单请求 + 策略 + 资源路由?的主要内容,如果未能解决你的问题,请参考以下文章