Обновите правила динамической проверки, добавив новые данные в контроллер - PullRequest
0 голосов
/ 09 мая 2019

Я работаю над веб-приложением, и технический стек: VueJS , для уровня презентации, Laravel (PHP) для RESTFUL API service, и база данных на основе nosql с именем neo4j .Вот контекст проблемы, у меня есть модель с именем 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 - В пользовательском интерфейсе, когда пользователь впервые открывает сообщение, создать сообщение Форма , он как общие поля для заполнения, как определено в 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 в <select>, которое загружает все типы контента из модели ContentType в database(throug ajax). Eg : Event,Link,File,..., и как только он выбирает тип, другой request(ajax) отправляется для извлеченияCustomField. Обратите внимание, что здесь настраиваемое поле означает, что для поля типа Event отправляются в следующем формате ['field_name'=>'name','field_type'=>'string','field_order'=>'1',validation_rules=>'required|max:200'] и т. Д., И я использую эти поля attributes для динамического построения моего PostType fields в Front-End, и как только пользователь заполняет форму и отправляет данные на внутренний сервер: у меня нет идеи, как обрабатывать проверку. Что я сделал первым, и это сработало, былосоздать запрос формы для всех моих пользовательских inputs field, но я не представляю, если вместо простого Event,File and Link Post types я добавлю 20. Я не буду создавать 20 правил проверки. На данный момент мой контроллер знает только какпроверить 'Post' следующим образом:

public function store(StorePost $request)
    {
        $data = $request->validated();
        ...
}

Я хотел бы обновить проверку existe StorePost новыми полями и новыми правилами в соответствии с данными, поступающими из front-end. Так что я не делаюЯ имею представление о том, как обновить существующее Form Request определение в папке «Запросы» в моем контроллере, и на основе данных, которые поступают из внешнего интерфейса, созданы новые правила проверки, основанные на определениях и заполненных полях в переднем конце.получил идею, заключающуюся в том, чтобы получить все правила проверки input_fields на основе посттипов, которые мне отправляет интерфейс, а затем обновить существующие правила проверки.

Примечание: способ, которым я определил relashionship, отличается от Eloquent, потому что я использую Neoloquent, который реализует neo4j базу данных.

1 Ответ

1 голос
/ 09 мая 2019

Вы можете динамически создавать свои правила проверки, используя данные из запроса:

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;
    }
}
...