Обеспечение уникальности по нескольким столбцам в Laravel

  1. Уникальное правило с замыканием.
    Вы можете использовать уникальное правило с замыканием, чтобы определить собственное правило проверки. Вот пример, который обеспечивает уникальность трех столбцов (column1, column2и column3) в таблице базы данных:
use Illuminate\Validation\Rule;
$validator = Validator::make($data, [
    'column1' => [
        'required',
        Rule::unique('table_name')->where(function ($query) use ($data) {
            return $query->where('column2', $data['column2'])
                         ->where('column3', $data['column3']);
        }),
    ],
    // other validation rules...
]);
if ($validator->fails()) {
    // Handle validation failure...
}
  1. Составной уникальный индекс.
    Другой подход заключается в создании составного уникального индекса для нужных столбцов в схеме базы данных. Это обеспечивает уникальность на уровне базы данных. Вот пример использования миграции в Laravel:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateYourTable extends Migration
{
    public function up()
    {
        Schema::create('table_name', function (Blueprint $table) {
            $table->id();
            $table->string('column1');
            $table->string('column2');
            $table->string('column3');

            $table->unique(['column1', 'column2', 'column3']);

            // other columns and constraints...
        });
    }
//...
}
  1. Пользовательское правило проверки.
    Вы можете создать собственное правило проверки, которое проверяет уникальность нескольких столбцов. Вот пример:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;
class UniqueAcrossColumns implements Rule
{
    protected $table;
    protected $columns;
    public function __construct($table, $columns)
    {
        $this->table = $table;
        $this->columns = $columns;
    }
    public function passes($attribute, $value)
    {
        $query = DB::table($this->table);
        foreach ($this->columns as $column) {
            $query->where($column, $value);
        }
        return $query->doesntExist();
    }
    public function message()
    {
        return 'The combination of columns is not unique.';
    }
}

Затем вы можете использовать специальное правило для проверки:

use App\Rules\UniqueAcrossColumns;
$validator = Validator::make($data, [
    'column1' => [
        'required',
        new UniqueAcrossColumns('table_name', ['column2', 'column3']),
    ],
    // other validation rules...
]);
if ($validator->fails()) {
    // Handle validation failure...
}