我有一个包含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
方法一起使用,并选择性地应用所需的规则?
我基本上为两个请求都使用了一个抽象基类,然后在子类中添加任何所需的规则。这将保留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'],
];
}
}
然后是两个子类:
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'],
]);
}
}
您应该在需要的地方使用其中一个子类,它们都将包含基类中的规则和它们自己的规则。
这比公认的答案要好,因为表格本身明确地说明了他们以自己的名义做什么,而不仅仅适用于一个条件(不清楚他们检查了什么(。
由于您正在使用方法$this->prepInput();
,我建议您更改一点代码以重用。
- 您必须为两个路由创建命名路由create&编辑我想你正在使用足智多谋的路由
-
更改您的代码,如下面的
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 | AppHttpControllersMyProjectsController@edit
所以我的myprojects
实体的id是$this->myprojects
。如果它为空,它将创建一个myprojects
,如果它有一个值,它将更新相应的myprojects
。
我使用单独的Rule
类,它们基本上只存储我在FormRequest
类中使用和重用所需的$rules
和$messages
。
class RulePrep
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
class RuleProjects
{
/**
* @var array
*/
public $rules = [];
/**
* @var array
*/
public $messages = [];
}
你可以试试吗?您需要单独的FormRequest类,但它可能比所有绑定到一个带有条件逻辑的类中更整洁。