Laravel 5.1 当一种方法需要一个字段而另一种方法不需要时,如何对两种方法使用相同的表单请求规则?
Laravel 5.1 How to use the same form request rules for two methods when a field is required in one but not in the other method?
我有一个包含 3 个文件输入字段的表单,用户应该至少上传一个文件。我有一个表单请求,我在其中验证它们如下:
public function rules()
{
$this->prepInput();
return [
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
}
为了更新相同的表单,我在我的控制器中使用了 update
方法,这与 store
方法几乎相同。唯一的区别是更新表单中不需要文件。有什么方法可以使用 store
和 update
方法使用相同的表单请求并选择性地应用所需的规则?
因为你正在使用一种方法$this->prepInput();
我建议你更改一点代码以重用。
- 您必须为路由创建和编辑创建命名路由。我假设你正在使用足智多谋的路由
像下面这样更改您的代码
public function isEditRequestCalled()
{
return app('router')->getCurrentRoute()->getName() == 'YOUR_EDIT_ROUTE_NAME';
}
并在您的请求方法中更改为这样
public function rules()
{
$this->prepInput();
return $this->isEditRequestCalled() ? [
//YOUR EDIT RULES GOES HERE
] : [//YOUR CREATE RULES GOES HERE
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
}
我使用了以下技巧并且奏效了:
public function rules()
{
$this->prepInput();
$rules= [
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
if($this->myprojects){
$rules['file1'] = 'between:1,15360|mimes:txt,pdf';
$rules['file2'] = 'between:1,15360|mimes:txt,pdf';
$rules['file3'] = 'between:1,15360|mimes:txt,pdf';
}
return $rules;
}
这里我的路线信息如下:
myprojects/{myprojects}/edit | myprojects.edit | App\Http\Controllers\MyProjectsController@edit
所以我的 myprojects
实体的 ID 是 $this->myprojects
。如果它是空的,它正在创建一个 myprojects
,如果它有一个值,它正在更新相应的 myprojects
.
我使用单独的 Rule
类,它基本上只存储 $rules
和 $messages
我需要在 FormRequest
[=19] 中使用和重复使用=].
class RulePrep
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
class RuleProjects
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
你可以试试吗?
您需要单独的 FormRequest 类,但它可能比所有捆绑在一起的条件逻辑更整洁。
我基本上是为我的两个请求使用抽象基础 class,然后在子classes 中添加任何需要的规则。这将保留 DRY 并提供一种灵活的方式来添加规则。例如:
abstract class CompanyBaseRequest extends FormRequest
{
...
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'category_id' => ['required', 'exists:company_categories,id'],
'short_description' => ['required', 'string', 'max:2000'],
'video' => ['nullable', 'file', 'mimes:mp4', 'max:30000'],
];
}
}
然后是两个子classes:
class CompanyStoreRequest extends CompanyBaseRequest
{
...
public function rules()
{
return array_merge(parent::rules(), [
'logo' => ['required', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
]);
}
}
class CompanyUpdateRequest extends CompanyBaseRequest
{
...
public function rules()
{
return array_merge(parent::rules(), [
'logo' => ['nullable', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
]);
}
}
您应该在需要时使用这些子class之一,它们都将包含来自基础 class 的规则和来自它们自身的规则。
这比接受的答案更好,因为表格本身明确说明了他们以自己的名义所做的事情,而不是只在一个条件下工作(不清楚他们检查的是什么)。
我有一个包含 3 个文件输入字段的表单,用户应该至少上传一个文件。我有一个表单请求,我在其中验证它们如下:
public function rules()
{
$this->prepInput();
return [
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
}
为了更新相同的表单,我在我的控制器中使用了 update
方法,这与 store
方法几乎相同。唯一的区别是更新表单中不需要文件。有什么方法可以使用 store
和 update
方法使用相同的表单请求并选择性地应用所需的规则?
因为你正在使用一种方法$this->prepInput();
我建议你更改一点代码以重用。
- 您必须为路由创建和编辑创建命名路由。我假设你正在使用足智多谋的路由
像下面这样更改您的代码
public function isEditRequestCalled() { return app('router')->getCurrentRoute()->getName() == 'YOUR_EDIT_ROUTE_NAME'; }
并在您的请求方法中更改为这样
public function rules()
{
$this->prepInput();
return $this->isEditRequestCalled() ? [
//YOUR EDIT RULES GOES HERE
] : [//YOUR CREATE RULES GOES HERE
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
}
我使用了以下技巧并且奏效了:
public function rules()
{
$this->prepInput();
$rules= [
'comment' => 'max:2000',
'source' => 'different:target',
'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
];
if($this->myprojects){
$rules['file1'] = 'between:1,15360|mimes:txt,pdf';
$rules['file2'] = 'between:1,15360|mimes:txt,pdf';
$rules['file3'] = 'between:1,15360|mimes:txt,pdf';
}
return $rules;
}
这里我的路线信息如下:
myprojects/{myprojects}/edit | myprojects.edit | App\Http\Controllers\MyProjectsController@edit
所以我的 myprojects
实体的 ID 是 $this->myprojects
。如果它是空的,它正在创建一个 myprojects
,如果它有一个值,它正在更新相应的 myprojects
.
我使用单独的 Rule
类,它基本上只存储 $rules
和 $messages
我需要在 FormRequest
[=19] 中使用和重复使用=].
class RulePrep
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
class RuleProjects
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
你可以试试吗? 您需要单独的 FormRequest 类,但它可能比所有捆绑在一起的条件逻辑更整洁。
我基本上是为我的两个请求使用抽象基础 class,然后在子classes 中添加任何需要的规则。这将保留 DRY 并提供一种灵活的方式来添加规则。例如:
abstract class CompanyBaseRequest extends FormRequest
{
...
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'category_id' => ['required', 'exists:company_categories,id'],
'short_description' => ['required', 'string', 'max:2000'],
'video' => ['nullable', 'file', 'mimes:mp4', 'max:30000'],
];
}
}
然后是两个子classes:
class CompanyStoreRequest extends CompanyBaseRequest
{
...
public function rules()
{
return array_merge(parent::rules(), [
'logo' => ['required', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
]);
}
}
class CompanyUpdateRequest extends CompanyBaseRequest
{
...
public function rules()
{
return array_merge(parent::rules(), [
'logo' => ['nullable', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
]);
}
}
您应该在需要时使用这些子class之一,它们都将包含来自基础 class 的规则和来自它们自身的规则。
这比接受的答案更好,因为表格本身明确说明了他们以自己的名义所做的事情,而不是只在一个条件下工作(不清楚他们检查的是什么)。