Laravel Validation: Exists with Additional Column Condition - Custom Validation Rule

Laravel validation: exists with additional column condition - custom validation rule

You want a custom validation rule, and I would create a separate class for this. But for brevity here's pretty much the same using inline closure:

// give it meaningful name, I'll go with game_fixture as an example
Validator::extend('game_fixture', function ($attribute, $value, $parameters, $validator)
{
if (count($parameters) < 4)
{
throw new \InvalidArgumentException("Validation rule game_fixture requires 4 parameters.");
}

$input = $validator->getData();
$verifier = $validator->getPresenceVerifier();

$collection = $parameters[0];
$column = $parameters[1];
$extra = [$parameters[2] => array_get($input, $parameters[3])];

$count = $verifier->getMultiCount($collection, $column, (array) $value, $extra);

return $count >= 1;
});

Then use simply this:

$rules = array(
'game_id' => 'required|exists:games,id',

// last parameter here refers to the 'game_id' value passed to the validator
'team1_id' => 'required|game_fixture:teams,id,game_id,game_id',
'team2_id' => 'required|game_fixture:teams,id,game_id,game_id'
);

Custom validation rule checking existence with column name and filter

Laravel is going to assume the column name from the data index, if you don't explicitly state the column name. In this case, address.state.

When you have tried to add the column name, you're not passing it as a second argument in it's own right. Try the following instead:

Rule::exists('shop_address_states', 'id')->where(function ($query) {
$query->where('country_id', 1);
});

Laravel exists custom validation rule unable to validate user id with phpunit

In your Rule::exists(), you need to specify column otherwise laravel takes the field name as column name

Rule::exists('authors', 'id')

Since column was not specified, your code was basically doing

Rule::exists('authors', 'author_id')

Laravel validation rule: unique with additional condition

You can specify where conditions in the unique rule.

'email' => [
"required",
Rule::unique('users')->where(fn ($query) => $query->where('platform', request()->platform)), //assuming the request has platform information
];

And, to ensure uniqueness at the database level, you might want to define the email and platform as a composite unique key

In the migration:

$table->unique(['email','platform']);

Reference:
https://laravel.com/docs/9.x/validation#rule-unique under the headline: Adding Additional Where Clauses:

https://laravel.com/docs/9.x/migrations#creating-indexes to get more information about creating composite indexes in Laravel.

Advice: RTFM

Using Laravel Exists Validation with a condition specified with a function

The encapsulation of the rules in single quotes means that the contents are taken literally. This means that the validation rule is looking for a company ID which is literally '\Auth::user()->active_company' as opposed to the output of that, perhaps 1 for the sake of example.

See the single quoted strings manual page

There are few ways you could do it:

  • Break out of the quotes and concatenate the two strings with a period (.)

    public static $rules = [
    'item' => 'exists:items,item,company_id,'.\Auth::user()->active_company,
    'location' => 'exists:locations,location,company_id,'.\Auth::user()->active_company,
    ];
  • Write active_company to a variable and break out of the quotes and concatenate the two strings with a period (.)

    $activeCo = \Auth::user()->active_company;

    public static $rules = [
    'item' => 'exists:items,item,company_id,'.$activeCo,
    'location' => 'exists:locations,location,company_id,'.$activeCo,
    ];
  • Write active_company to a variable and use double quotes as variables are expanded/interpreted inside double ones. "$activeCo" or "{$activeCo}" will work

    $activeCo = \Auth::user()->active_company;

    public static $rules = [
    'item' => "exists:items,item,company_id,{$activeCo}",
    'location' => "exists:locations,location,company_id,{$activeCo}",
    ];

Using models relationships in Laravel Validation Rule 'Exists'

I would use this. This will solve your problem, but i don't know either is the best way or not.

    use Validator; // on the top

$validator = Validator::make($request->all(), [
'user_id' => 'nullable|numeric|exists:users,id',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
$user = User::find($request->user_id);
if(!$user || !$user->roles->first() || $user->roles->first()->id != 4) {
return response()->json(['user_id'=>['You dont have permission.']], 422);
}

Another way you can try

'user_id'  => [
'nullable',
'numeric',
'exists:users,id',
function ($attribute, $value, $fail) {
$editorsIDs = User::whereHas('roles', function ($q) {
$q->where('id', 4);
})->pluck('id');

if(! $editorsIDs->contains($value)) {
$fail('You dont have permission.');
}}
]

How can I add a join to a custom exists rule for a laravel validator?

It seems that the DatabaseRule does some magic with whatever you provided in that closure. In the end, it only seems to look at provided where clauses (see Exists::__toString). The joins have been saved as the echo inside the closure shows, but then the exists rule only looks at the where. That's the reason for the unknown column error it seems.

I did try the using function, which seems better suited than the where I had in there first, but that doesn't help, as the system makes it into a string, which forms a validation-string that just doesn't seem to support joins.

Long story short, I just created a custom validation rule with the passes function looking something like this:

public function passes($attribute, $value)
{
$count = DB::table('staff')
->join('teams', 'teams.team_id', '=', 'staff.team_id')
->where([
['teams.active', '=', 1],
['staff.email', '=', $value]
])->count();

return $count > 0;
}


Related Topics



Leave a reply



Submit