复杂更新验证的逻辑应该放在哪里?

Where should the logic for complex update validation live?

我正在与我的团队讨论并利用 Laravel 框架。

验证对作为关系的现有模型属性的更新需要一些数据库调用以确保它符合约束条件。

我的第一个想法是创建一个自定义验证器,但是,这需要在验证器内进行查询。一种是获取正在更新的模型,一种是获取存在的关系,另一种是获取将被更新的关系。这个验证器也只会用于更新这个模型上的这个属性。

或者,这可以通过事件进行验证,但我不确定保留该验证逻辑的最佳位置。

如有任何建议,我们将不胜感激。

Laravel 的自定义验证规则几乎就是为此

制定的
use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);

您可以在查询中添加任何您想要的约束,只要返回至少 1 条记录,它就会通过

编辑表单验证放置的命名空间App\Http\Requests\Post;

namespace App\Http\Requests\Post;

use Illuminate\Foundation\Http\FormRequest;

class EditFormValidation extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required | max:150 | unique:posts,title,'.$this->request->get('id'),
            'description' => 'required'
        ];
    }

    public function messages()
    {
        return [
            'title.required' => 'This filed is required.',
        ];
    }
}

然后在控制器中

public function update(EditFormValidation $request)
    {
        $row = Post::find($request->get('id'));
        $row->update([
            'title' => $request->get('title'),
            'slug' => str_slug($request->get('title')),
            'description' => $request->get('description'),
            'status' => $request->get('status')
        ]);

        $request->session()->flash('success_message', 'Post successfully updated.');
        return redirect()->to('post');
    }