I have a Restaurant Model, each restaurant has a Contact Model, and each Contact is related to a City Model:
Restaurant.php:
public function contact()
{
return $this->hasOne('App\Contact','rest_id');
}
Contact.php:
public function restaurant()
{
return $this->belongsTo('App\Restaurant','rest_id','id');
}
public function city()
{
return $this->belongsTo('App\City');
}
City.php:
public function contacts()
{
return $this->hasMany('App\Contact');
}
now, what I want to do is search the restaurant names, alongside city names.
my controller code for searching is like this:
// the purpose of this condition is to keep the query empty until applying desired filters
$data = Restaurant::where('id', '=', '0');
$cityRest=$request->cityRest ;
if (!empty($cityRest)) {
$nameFilter = Restaurant::where('name', 'like', "%$cityRest%");
$contactFilter = Restaurant::whereHas('contact', function ($contact) use ($cityRest) {
$contact->where('address', 'like', "%$cityRest%");
$contact->whereHas('city', function ($city) use ($cityRest) {
$city->where('cityName', 'like', "%$cityRest%");
});
});
$data = $data->union($nameFilter);
$data = $data->union($contactFilter);
}
$data->get();
when searching for restaurant name,the results are returned correctly,but when searching for city names nothing is returned, although there is restaurants with contact models that has a city???
You have to use a orWhereHas
instead of a whereHas
.
With the whereHas
you are searching for restaurants where the contact.address
AND the city.name
match your input.
By using the orWhereHas
you are searching for restaurants where the contact.address
OR the city.name
match your input.
The AND and OR operators are used to filter records based on more than one condition:
Try this:
$contactFilter = Restaurant::whereHas('contact', function ($contact) use ($cityRest) {
$contact->where('address', 'like', "%$cityRest%");
$contact->orWhereHas('city', function ($city) use ($cityRest) {
$city->where('cityName', 'like', "%$cityRest%");
});
});