通过在控制器中添加新数据来动态更新验证规则 [英] Update dynamically validation rules by adding new data in the controller
问题描述
我正在开发一个基于Web的应用程序,技术堆栈为: VueJS ,用于表示层, Laravel(PHP),用于 RESTFUL API 服务,以及名为 neo4j 的基于nosql图的数据库.这是问题的上下文,我有一个名为 Post 的模型,并且在此定义的属性将共享所有帖子类型,因此它们所有人都将拥有它:
I'm working on a web based app,and the Tech stack is : VueJS,for the presentation layer, Laravel (PHP) for RESTFUL API service,and a nosql graph based database called neo4j. Here is the problem context, I have a model called Post, and attributes that are defined here are shared all the post type,so all of them will have it:
use NeoEloquent;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
use Vinelab\NeoEloquent\Eloquent\SoftDeletes;
class Post extends NeoEloquent
{
protected $label = 'Post';
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title',
'slug',
'body',
'status',
'image',
'published_at',
'read_time',
'isModerate',
'link',
'external_id'
];
/**
protected $hidden = ['remember_token'];
/**
* relations
*/
public function authors()
{
return $this->belongstoMany('App\User', 'AUTHOR');
}
public function getSlugOptions(): SlugOptions
{
return SlugOptions::create()->generateSlugsFrom('title')->saveSlugsTo('slug');
}
//Post type
public function contentType(){
return $this->hasOne('App\ContentType','IS_OF_TYPE');
}
}
PostType :这里的类型可以是文件,链接,事件等.例如: [name=>'Event','description'=>'description','slug'=>'event']
PostType : Here the type can be a File,Link,an Event,etc.Eg : [name=>'Event','description'=>'description','slug'=>'event']
class PostType extends NeoEloquent
{
protected $label='ContentType';
protected $dates=['created_at','updated_at','deleted_at'];
protected $fillable=[
"name",
"description",
"slug"
];
//Ce input contentype sera associe a plusieurs input fields
public function customFields(){
return $this->belongsToMany('App\CustomField',"HAS_FIELD");
}
public function post(){
return $this->belongsToMany('App\Post','IS_OF_TYPE');
}
}
最后是 CustomField 模型:
class CustomField extends NeoEloquent
{
protected $label="CustomType";
protected $dates=["created_at","updated_at","deleted_at"];
protected $fillable=[
"field_name",
"field_type",
"field_order",
"validation_rules"
];
public function contentTypes(){
return $this->belongsToMany('App\CustomField','HAS_FIELD');
}
}
因此,流程如下:
1-在UI中,当用户首次打开帖子时,创建帖子 Form ,他是根据Post
模型的fillable
属性定义的要填充的通用字段.为此,已经有了一个Form验证请求定义如下:
So here is the flow:
1 - In the UI when user first open the post create post Form ,he as the common fields to fill as defined in fillable
propertie of Post
model.And for that,already have a Form Request for validation defines like this :
class StorePost extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required|string|min:1',
'body' => 'required',
'status' => 'required',
'image' => 'sometimes|image',
'published_at' => 'required',
'link' => 'required_if:type,==,RSS|required_if:type,==,LINK',
'external_id' => 'sometimes'
];
}
}
2-以相同的形式,用户在<select>
中具有type
字段,该字段将加载database(throug ajax)
中ContentType
模型中的所有内容类型.Eg : Event,Link,File,...
,并且一旦他选择了另一个类型request(ajax)
去检索CustomField
.请注意,此处的自定义字段表示对于类型Event
的字段,其格式如下['field_name'=>'name','field_type'=>'string','field_order'=>'1',validation_rules=>'required|max:200']
等.我使用这些字段属性来动态构建<Front-End
中的c12>,并且一旦用户填写表单并在后端服务器中发送数据:我不知道如何处理验证.我首先要做的是创建一个Form Request for我所有的自定义inputs field
,但我不知道是否要添加20,而不是仅仅添加Event,File and Link
Post types
.我不会创建20条验证规则.这时我的控制器仅知道如何验证"Post" :
2 - In the same form,the user has type
field in a <select>
that loads all the content types from ContentType
model in the database(throug ajax)
.Eg : Event,Link,File,...
and once he chooses a type another request(ajax)
goes to retrieve the the CustomField
.Note that here custom field mean that,for a type Event
field are send in the following format ['field_name'=>'name','field_type'=>'string','field_order'=>'1',validation_rules=>'required|max:200']
,etc.. and i use those field attributes to dynamically build my PostType fields
in the Front-End
,and once the user fills the form and send data in the backend server:I don't have the idea of how to handle validation.What i did first and it worked was to create a Form Request for all my custom inputs field
,but no i imagine if instead of just having Event,File and Link
Post types
i add 20.I won't create 20 validation rules.At this point my controller only knows how to validate 'Post' like this :
public function store(StorePost $request)
{
$data = $request->validated();
...
}
我想做的是根据来自前端的数据用新的字段和新的规则更新现有的StorePost验证.所以我不知道如何更新现有的Form Request
定义在控制器的Requests文件夹中,并根据前端提供的数据,根据前端的定义和填充字段创建新的验证规则.我有个主意,包括根据以下内容提取所有input_fields验证规则前端发送给我的帖子类型,然后更新现有的验证规则.
What i would like to do is the update the existe StorePost validation with new fields and new rules according to data comming from the front-end.So i don't have any idea of how to update the existing Form Request
define in the Requests folder in my controller,and based on data that comes from front-end created new validation rules based on defines and filled fields on the front -end.I've got an idea,the consiste of fetching all input_fields validation rules based on posttypes that front-end sends to me,and then update the existing validation rules.
注意:我定义冲突关系的方式与Eloquent
不同,因为我正在使用实现neo4j
数据库的Neoloquent
.
Note : The way that i've defined relashionship is different with Eloquent
because i'm using Neoloquent
that implements neo4j
database.
推荐答案
您可以使用请求中的数据动态构建验证规则:
You can dynamically build your validation rules using data from the request:
use Illuminate\Http\Request;
class StorePost extends FormRequest
{
public function authorize()
{
return true;
}
public function rules(Request $request)
{
$rules = [
'title' => 'required|string|min:1',
'body' => 'required',
'status' => 'required',
'image' => 'sometimes|image',
'published_at' => 'required',
'link' => 'required_if:type,==,RSS|required_if:type,==,LINK',
'external_id' => 'sometimes'
];
if($typeSlug = $request->get('type'))
{
$type = PostType::where('slug', $typeSlug)->with('customFields');
// map custom fields into a `['name' => 'rules']` format
$customFieldRules = $type->customFields->mapWithKeys(function($customField) {
return [$customField->field_name => $customField->validation_rules];
});
$rules = array_merge($rules, $customFieldRules);
}
return $rules;
}
}
这篇关于通过在控制器中添加新数据来动态更新验证规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!