Livewire3.0(Laravel10)多表唯一性验证报错:列不存在
多表关联唯一性验证报错解决(Livewire 3.0 + Laravel 10)
问题场景
要实现同一grupo_id下无法创建同名的resultados_aprendizaje记录,通过Rule::unique关联resultados_aprendizaje和criterios_evaluacion表时,出现SQLSTATE[42S22]列不存在错误,生成的SQL未正确执行JOIN操作。
原代码
$validated = $this->validate([ 'nombre' => [ 'required', Rule::unique('resultados_aprendizaje','nombre')->where(function (Builder $query) use ($grupoId) { return $query->join('criterios_evaluacion', 'resultados_aprendizaje.id', '=', 'criterios_evaluacion.ra_id')->where('criterios_evaluacion.grupo_id', $grupoId); }) ], ]);
表结构
resultados_aprendizaje('id','nombre') criterios_evaluacion('id','nombre','ra_id','grupo_id')
错误信息
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'criterios_evaluacion.grupo_id' in 'where clause'
生成的错误SQL
select count(*) as aggregate from `resultados_aprendizaje` where `nombre` = RA and (`criterios_evaluacion`.`grupo_id` = 5)
解决方案
原因分析
Laravel的Rule::unique底层会重置查询的from部分,直接在where闭包里添加join会被框架过滤,导致生成的SQL中没有JOIN语句,自然找不到关联表的列。
修改后的代码(使用whereExists子查询)
use Illuminate\Database\Query\Builder; use Illuminate\Support\Facades\DB; $validated = $this->validate([ 'nombre' => [ 'required', Rule::unique('resultados_aprendizaje', 'nombre')->where(function (Builder $query) use ($grupoId) { return $query->whereExists(function ($subQuery) use ($grupoId) { $subQuery->select(DB::raw(1)) ->from('criterios_evaluacion') ->whereColumn('criterios_evaluacion.ra_id', 'resultados_aprendizaje.id') ->where('criterios_evaluacion.grupo_id', $grupoId); }); }) ], ]);
说明
通过whereExists子查询关联criterios_evaluacion表,主查询会检查是否存在关联指定grupo_id的resultados_aprendizaje记录,这种方式不会被Rule::unique的底层逻辑过滤,能正确生成包含关联条件的SQL。
如果是更新场景,需要排除当前记录,可以在Rule::unique后追加ignore($this->ra->id)(假设当前记录ID存在于$this->ra->id)。
内容的提问来源于stack exchange,提问作者José L.
相关产品推荐
相关产品推荐

