>我有一个名为records
的表,其中有一个user_id
列,链接到一个users
表以设置所有权。
我可以使用搜索字符串按title
正确过滤记录:
$records->where('title', 'LIKE', '%'.$search.'%');
但我还想返回包含users.firstname
和users.lastname
的结果,这是我(可怕的)加入尝试:
$records->join('users', 'users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%')
->orWhere('title', 'LIKE', '%'.$search.'%');
// SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous
在我等待更好的答案时,我找到了一个有效的解决方案,但它不是最佳的,因为它涉及一个额外的查询来收集作者user_id
并随后使用它来查询records
:
// Get the author ID
$author = DB::table('users')
->select(DB::raw('CONCAT_WS(" ",`firstname`,`lastname`) as `fullname`,id'))
->having('fullname', 'LIKE', '%'.$search.'%')
->first();
// $author output:
stdClass Object
(
[fullname] => John Doe
[id] => 35
)
// Query the records using the gathered ID
$records->where('user_id', $author->id)
->orWhere('title', 'LIKE', '%'.$search.'%');
此解决方案的问题:除了额外的查询之外,如果有人搜索John Doe
或Some Title
,结果是正确的。但是如果搜索John Doe Some Title
,则不会显示任何内容,因为找不到作者和标题。
您需要在内部查询中使用搜索参数进行设置:
$records->join('users', function($join) use ($search)
{
$join->on('users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%');
});
如果我知道您想通过使用$search过滤从记录返回结果,并且还想显示此记录的用户信息。您可以使用雄辩。您的模型必须是:
在用户模型中:
public function records()
{
return $this->hasMany(Record::class);
}
在记录模型中:
public function user()
{
return $this->belongsTo(User::class);
}
在控制器中:
Record::where('title', 'LIKE', '%'.$search.'%')
->with('user')
->first();