Let's say you have this relationship: users
x cats
. Each user can have many cats (a "one-to-many" relationship):
class Cat extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Both models (users and cats) have a name
field.
Let's say we want to get all cats with bob
in their names, using Laravel's Scout.
The standard solution is to add this to the Cat.php
model:
// Cat.php
use Searchable;
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
return [
'name' => $this->name,
];
}
And we search with Cat::search('bob')->get()
.
The problem
The above solution works well, but what if we want to search in the relationship's fields?
What if you want to get cats owned by people with bob
in their names?
If you add this to the "Cat" model:
// Cat.php
use Searchable;
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
return [
'name' => $this->name,
'users.name' => '', // no need to return `$this->user->name` as the database engine only uses the array keys
];
}
It won't work. You will get this exception when running Cat::search('bob')->get()
:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.name' in 'where clause'
SQL: select `cats`.* from `cats` where (`cats`.`name` like %bob% or `users`.`name` like %bob%)
Clearly, the SQL is missing the users
table. But how to add it? Doing a Cat::join(...)->search('bob')
will throw an exception, same for Cat::search(...)->join(...)
.
The question is: How to search in the parent attributes? And by "parent" I mean the "belongsTo" model.