我在使用Laravel身份验证时遇到了问题。当我登录时,Laravel返回错误:"子句中的'id'列不明确",因为我有一个具有JOIN的GlobalScope。
错误:
Column 'id' in where clause is ambiguous (SQL: select * from `users` inner join `playables` as `p` on `users`.`id` = `p`.`user_id` inner join `league_of_legends` as `lol` on `p`.`playable_id` = `lol`.`id` and `p`.`playable_type` like '%LeagueOfLegends%' where `id` = 1 and `users`.`deleted_at` is null and `users`.`banned` = 0 limit 1)
登录代码:
Auth::login($user);
全球范围:
$builder->join('playables as p', 'users.id', '=', 'p.user_id')
->join('league_of_legends as lol', function ($join) use ($game){
$join->on( 'p.playable_id', '=', 'lol.id');
$join->on('p.playable_type', 'like', DB::raw( "'%$game%'"));
});
我试图重命名模型用户的主键,但这会导致其他错误。有其他选择吗?或者我必须使用本地作用域?
谢谢。
如果您像我一样使用 Eloquent Builder,解决方案是在具有全局范围的模型上指定主键名称:
protected $primaryKey = "users.id";
Builder
将其where
子句公开存储在数组中,$builder->wheres
.
因此,您可以访问和修改变量。但仅限于这一次,因为显然这不是正确的方式。
现在的$builder->wheres
是这样的
array(3) {
[0]=>
array(5) {
["type"]=> string(5) "Basic"
["column"]=> string(2) "id"
["operator"]=> string(1) "="
["value"]=> string(1) "1"
["boolean"]=> string(3) "and"
}
// ... Others are array of column deleted_at and banned
}
因此,只需循环$builder->wheres
并将其修改为
foreach( $builder->wheres as $key => $item ){
// Only modify column of 'id'
if( $item['column'] == 'id' ){
$builder->wheres[$key]['column'] = 'users.id';
break;
}
}
您可以将第二个join
子句作为where
子句
$builder->join( 'league_of_legends AS lol', function( $join ){
$join->on( 'p.playable_id', '=', 'lol.id');
})->where( 'p.playable_type', 'LIKE', DB::raw( "'%$game%'") );
最后为用户做select
// This also reset the SQL SELECT that previously defined
$builder->select( 'users.* AS users' );
所以它会是
foreach( $builder->wheres as $key => $item ){
// Only modify column of 'id'
if( $item['column'] == 'id' ){
$builder->wheres[$key]['column'] = 'users.id';
break;
}
}
$builder
->select( 'users.* AS users' )
->join( 'playables AS p', 'users.id', '=', 'p.user_id' )
->join( 'league_of_legends AS lol', function( $join ){
$join->on( 'p.playable_id', '=', 'lol.id');
})->where( 'p.playable_type', 'LIKE', DB::raw( "'%$game%'") );