user7014175
user7014175

Reputation:

Validation rules in Laravel for joining two columns

Is there a way to build a validation in Laravel which checks if two columns together are unique in a table?

So for example if there is [(A, B)] in my table, then the input (A, A) or (B, B) should pass the validation but (A, B) again have to fail.

For example like this:

DB::table('mytable')
            ->where([
                ['col1', $item->col1],
                ['col2', $item->col2]
            ])
            ->exists();

But I want to do it within a validation, so something simular to this:

public function validate() {
        return Validator::make($this->attributes, [
            'col1|col2' => 'unique:mytable',
            //....
        ])->errors();
    }

Upvotes: 2

Views: 1956

Answers (2)

Frondor
Frondor

Reputation: 3466

If you are looking for validation of uniqueness of composite indexes (multiple columns), this is not possible unless you create a custom validation rule.

You can create a custom validation rule, see https://laravel.com/docs/validation#custom-validation-rules

// Example:
// 'col1' => 'unique_with:table,col2,col3,col4,etc'
// 'col2' => doesn't need to check uniqueness again, because we did it for col1

Validator::extend('unique_with', function ($attribute, $value, $parameters, $validator) {
    $request = request()->all();

  // $table is always the first parameter
  // You can extend it to use dots in order to specify: connection.database.table
  $table = array_shift($parameters);

  // Add current column to the $clauses array
  $clauses = [
    $attribute => $value,
  ];

  // Add the rest  
  foreach ($parameters as $column) {
    if (isset($request[$column])) {
        $clauses[$column] = $request[$column];
    }
  }

  // Query for existence.
  return ! DB::table($table)
            ->where($clauses)
            ->exists();
});

place that code in the boot() method of a service provider, you can use App\Http\Providers\AppServiceProvider.php I didn't test it, but it should help you to go forward and make the necessary adjustments.

Upvotes: 1

Ohgodwhy
Ohgodwhy

Reputation: 50787

I think what you're looking for is to require them if either exists, but make sure both are unique. This should work for you:

'col1' => 'unique:mytable|required_with:col2',
'col2' => 'unique:mytable|required_with:col1'

Upvotes: 0

Related Questions