php - 雄辩的碰撞列名称
问题描述
我有以下表格:
用户:id
, name
, ...
公司:id
, name
, ...
我有一个scope
带LIKE
运算符,我用它来搜索两者users.name
,companies.name
如下所示:
public function scopeSearch(Builder $query, string $term = null)
{
$query->join('companies', 'companies.id', '=', 'users.company_id');
$term = $term.'%';
$query->where('users.name', 'like', $term)
->orWhere('companies.name', 'like', $term);
}
行动:
$users = User::query()
->search($request->input('q'))
->with('company')
->paginate();
// ...
由于name
在两个表中都使用了,Laravel 无法区分它们,所以它最终users.name
用 a填充companies.name
:
视图如下所示:
@foreach($users as $user)
// ...
<th scope="row">{{ $user->id }}</th>
<td>{{ $user->name }}</td> // wrong: this gives the company.name
<td>{{ $user->company->name }}</td>
<td>{{ $user->email }}</td>
// ...
@endforeach
解决此问题的一种解决方案是使用select
和一些别名,但这将是一个讨厌的解决方案。
有什么好的解决办法吗?
更新 1:我不想使用whereHas
,因为在使用运算符时它比加入要慢LIKE
。
更新 2:另一种解决方案是别名 thecompanies.name
和users.name
如下:
public function scopeSearch(Builder $query, string $term = null)
{
$query->join('companies', 'companies.id', '=', 'users.company_id')
->select(['*', 'companies.name as company_name', 'users.name as user_name']);
}
<td>{{ $user->user_name }}</td>
<td>{{ $user->company_name }}</td>
这工作正常,但是如果(出于任何原因)我想摆脱搜索能力,我还需要修改视图,所以这里引入了一个依赖项。
解决方案
我可能会重写搜索范围以通过关系和使用搜索公司名称whereHas()
,而不是加入它。这样,在使用该范围时,您永远不会有模棱两可的列名。
它会生成不同的查询,但最终会得到相同的结果。
public function scopeSearch(Builder $query, string $term = null)
{
$term = $term.'%';
return $query->where('name', 'like', $term)
->orWhereHas('company', function($query) use ($term) {
return $query->where('name', 'like', $term);
});
}
推荐阅读
- mysql - 卸载 + 重新安装后查询数据库时出错:错误:ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'localhost'
- azure-devops - 如何在 Azure DevOps 中使用 yaml 从管道运行 git 命令
- python - 迭代单个字节,然后将其保存到文件中而不改变内容
- python - TypeError: __init__() 得到了一个意外的关键字参数 'feature'
- html - 消除页面顶部和导航之间的小间隙
- logging - log4j2 删除旧存档日志不起作用
- processing - 球在处理中远离光标项目
- kubernetes - 在 kustomize 中修补特定资源
- .net-core - 简单场景中的 net core 3.1 dep inj 错误,ILogger 奖金问题
- python - Pandas - 重新索引仅对具有唯一值的索引对象有效