Laragear / Rut

Gracefully handle RUTs from within your Laravel application
https://patreon.com/packagesforlaravel
MIT License
6 stars 0 forks source link

[3.x] RutUnique's Validation query does not work because the generated SQL is incorrect #39

Closed ipontt-neering closed 2 months ago

ipontt-neering commented 2 months ago

PHP & Platform

8.3

Database

MySQL 8

Laravel version

11.x

Have you done this?

Expectation

Assuming we have a User model with the default rut columns and the trait included:

User::factory()->create(['rut' => '11.111.111-1']);

$data = ['rut' => '11.111.111-1'];
$rules = ['rut' => ['required', 'rut_unique:users,rut_num'];

validator($data, $rules)->validate(); // ValidationException should be thrown.

Description

I've narrowed the problem to the Laragear\Rut\ValidatesRut::query protected method, where the following query is made:

$query = DB::connection($connection)
    ->table($table)
    ->where($num_column, $rut->num)
    ->whereRaw("UPPER(\"$vd_column\") = ?", strtoupper($rut->vd))
    ->when($wheres[0] ?? null, function (Builder $query) use ($wheres) {
        $query->where($wheres[1] ?? 'id', '!=', $wheres[0]);
    });

For the above example, the generated SQL query will be

select exists(select * from `users` where `rut_num` = ? and UPPER("rut_vd") = ?) as `exists`

Which will always return 0 (false) since UPPER("rut_vd") is not checking the column but a string literal "RUT_VD".

The easy fix is to change this line to

->whereRaw("UPPER($vd_column) = ?", strtoupper($rut->vd))

or

->whereRaw("UPPER({$vd_column}) = ?", strtoupper($rut->vd))

Reproduction

Assuming we have a `User` model with the default rut columns and the trait included:

User::factory()->create(['rut' => '11.111.111-1']);

$data = ['rut' => '11.111.111-1'];
$rules = ['rut' => ['required', 'rut_unique:users,rut_num'];

validator($data, $rules)->validate(); // ValidationException should be thrown.

Stack trace & logs

No response

ipontt-neering commented 2 months ago

I will submit a pr for this in a moment.