Laravel使用多个表搜索数据库


Laravel search DB with multiple tables

>我有一个名为records的表,其中有一个user_id列,链接到一个users表以设置所有权。

我可以使用搜索字符串按title正确过滤记录:

$records->where('title', 'LIKE', '%'.$search.'%');

但我还想返回包含users.firstnameusers.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 DoeSome 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();