Ответы пользователя по тегу Laravel
  • Как написать валидацию уникальности по двум полям laravel?

    YmNIK_13
    @YmNIK_13
    Вопросу уже год, но может еще кому пригодится.

    Вот как я решил подобное.

    В ларе ответы можно обрабатывать отдельно. наследуюсь от класса FormRequest, а у него в свою очередь есть прекрасный метод prepareForValidation() который позволяет предварительно обработать/очистить входящие параметры.

    Сам полученный объект имеет метод all() - где содержатся все входные параметры.

    Таким образом, в наследуемом классе от FormRequest я добавил поле для хранения второго параметра. а в методе prepareForValidation() его туда помещаю.

    Сама валидация проходит в методе rules() - где мы указываем правила.
    В нашем распоряжении есть класс Rule который позволяет кастомизировать проверку.

    Ниже мой класс который проверяет на уникальность два поля:
    name и parent_id

    namespace App\Http\Requests\Admin\Common;
    
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Validation\Rule;
    
    class SourceRequest extends FormRequest
    {
        protected $parent_id = null;
    
        protected function prepareForValidation()
        {
            $input = $this->all();
    
            // parent_id  - это int. который может быть и null, тут мы его сохраняем
            if (isset($input['parent_id'])) {
                $parent_id = intval($input['parent_id']);
                if ($parent_id > 0) {
                    $this->parent_id = $parent_id;
                }
            }
    
            $this->replace($input);
        }
    
    
        public function rules()
        {
            // передаем в запрос второй параметр
            $name_rule_uniq = Rule::unique('source')
                ->where(function ($query) {
                   // в зависимости от того какой parent_id добавляем правило
                    if ($this->parent_id !== null) {
                        $query->where([
                            ['parent_id', $this->parent_id],
                        ]);
                    } else {
                        $query->whereNull('parent_id');
                    }
                });
    
            // добавляем игнор если это текущая страница - это для редактирования
            $niche_id = $this->route()->parameter('source');
            if (!empty($niche_id)) {
                $name_rule_uniq->ignore($niche_id);
            }
    
    
            return [
                'name' => [
                    'required',
                    $name_rule_uniq,
                ],
            ];
        }
    
        // это вывод сообщений если при проверке повторяется имя или оно вообще отсутствует
        // можно не реализовывать
        public function messages()
        {
            return [
                'name.required' => ':attribute - обязательно',
                'name.unique' => ':attribute должно быть уникальным',
            ];
        }
    
        // это чтоб не писать одно и то же имя валидируемой переменной 
        // можно не реализовывать
        public function attributes()
        {
            return [
                'name' => 'Имя источника',
                'parent_id' => 'Id источника',
            ];
        }
    
    }
    Ответ написан
    1 комментарий