G
G
ganjo8882019-08-27 14:08:18
Laravel
ganjo888, 2019-08-27 14:08:18

How to write uniqueness validation on two laravel fields?

how to write uniqueness validation by combination of two fields "source_id" and 'text'
doesn't work like that

'source_id'   => 'unique:table_name, source_id,text',

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Anton Anton, 2019-08-27
@ganjo888

or a function:

$validator->after(function ($validator) use ($request, $current_item) {
            if (Items::where('id', '!=', $current_item['id'])->where('source_id', $request->input('source_id'))->where('text', $request->input('text'))->exists()) {
                $validator->errors()->add('source_id', 'Ошибка уникальности сочетания source_id и text');
            }
        });

or specify a unique composite index in the database (if column types allow): and catch an insert / save error

Y
YmNIK13, 2020-05-25
@YmNIK_13

The question is already a year old, but maybe it will be useful to someone else.
Here's how I solved it.
In Lara, responses can be processed separately. I inherit from the FormRequest class , and it, in turn, has a wonderful prepareForValidation() method that allows you to pre-process / clear incoming parameters.
The resulting object itself has an all() method - which contains all the input parameters.
Thus, in the class inherited from FormRequest, I added a field to store the second parameter. and in the prepareForValidation() method I put it there. The validation itself takes place in the rules()
method - where we specify the rules.
We have a Rule class that allows us to customize the check.
Below is my class that checks for uniqueness two fields:
name and 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 источника',
        ];
    }

}

O
oleg_ods, 2019-08-27
@oleg_ods

'source_id' => 'unique:table_name, source_id',
'text' => 'unique:table_name, text',
Is it that hard?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question