我正在开发一个基于Web的应用程序,技术堆栈为: VueJS ,用于表示层, Laravel(PHP),用于 RESTFUL API 服务,以及名为 neo4j 的基于nosql图的数据库。这是问题的上下文,我有一个名为 Post 的模型,并且在此定义的属性将共享所有帖子类型,因此它们都将拥有它:
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']
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 ,他是fillable
模型的Post
属性中定义的通用字段。为此,已经有一个表单请求验证定义,如下所示:
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-以相同的形式,用户在type
的{{1}}字段中加载<select>
中ContentType
模型中的所有内容类型。{{1 }},一旦他选择了一个类型,另一个database(throug ajax)
就去检索Eg : Event,Link,File,...
。请注意,此处的自定义字段表示,对于类型为request(ajax)
的字段,其格式为{{ 1}}等。我使用这些字段属性在CustomField
中动态构建我的Event
,并且一旦用户填写表单并在后端服务器中发送数据,我就没有了:我首先要做的是为所有自定义['field_name'=>'name','field_type'=>'string','field_order'=>'1',validation_rules=>'required|max:200']
创建一个表单请求,但我没有想过是否要拥有PostType fields
Front-End
我添加20,我不会创建20条验证规则。此时,我的控制器仅知道如何验证“ Post”,如下所示:
inputs field
我想做的是根据来自前端的数据用新的字段和新的规则更新现有的StorePost验证。因此,我不知道如何更新现有的{{1} }在控制器的Requests文件夹中进行定义,并根据来自前端的数据基于前端的定义和填充字段创建新的验证规则。我有一个主意,包括获取所有input_fields验证基于前端发送给我的帖子类型的规则,然后更新现有的验证规则。
注意:我定义冲突关系的方式与Event,File and Link
不同,因为我使用的是实现Post types
数据库的public function store(StorePost $request)
{
$data = $request->validated();
...
}
。
答案 0 :(得分:1)
您可以使用请求中的数据动态构建验证规则:
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;
}
}