Laravel search query with oneToMany foreign table value - laravel

I have 2 tables
Entry
- id
- title
- submitter_name
- client_name
- agency_id
Agency
- id
- name
Entry Model
public function agency(){
return $this->belongsTo('App\Agency');
}
and Agency Model
public function entries(){
return $this->hasMany('App\Entry', 'entry');
}
I need to find all Entrys from database based on title,submitter_name,client_name,agency_name
The first 3 are easy
public function searchByData(Request $request) {
$Entrys = Entry::where('title', 'LIKE', '%'.$request->title.'%')
->where('submitter_name', 'LIKE', '%'.$request->submitter_name.'%')
->where('client_name', 'LIKE', '%'.$request->client_name.'%')
->get();
return view('entries.index')->with($Entrys);
But I'm failing miserably in finding Entries based on agency name.

try this:
public function searchByData(Request $request) {
$Entrys = Entry::where('title', 'LIKE', '%'.$request->title.'%')
->where('submitter_name', 'LIKE', '%'.$request->submitter_name.'%')
->where('client_name', 'LIKE', '%'.$request->client_name.'%')
->whereHas('agency, function($query) use($request){
$query->where('name', 'LIKE', '%' . $request->agency_name . '%');
})
->get();
return view('entries.index')->with($Entrys);

Related

Laravel Query Through Relationship

I am creating a search in laravel where customers can search for vehicles.
Table 1
Vehicle
VIN
PLATE
make_and_model_id
Table 2
Vehicle Makes and Models
id
make
model
Relationship in Table 1: Vehicle
public function vehicle_make_and_model_fk()
{
return $this->belongsTo('App\Models\VehicleMakeAndModel', 'vehicle_make_and_model_id');
}
So I am searching for VIN or Plate. That works fine.
I also am Searching for a Make and Model name which is a foreign key.
I pulled in the related table using with which works fine.
Now how to search through the columns of Make and Model Table?
if($request->ajax()) {
$search = $request->search_query;
$vehicles = Vehicle::with('vehicle_make_and_model_fk')
->where(function ($query) use ($search) {
$query->where('plate', 'LIKE', '%'.$search.'%')
->orWhere('vin', 'LIKE', '%'.$search.'%')
->orWhere('vehicle_make_and_models.make', 'LIKE', '%'.$search.'%');
})
->limit(5)
->get();
echo json_encode($vehicles);
exit;
}
To filter the relationship, you need to use a closure in your with()
For example:
$vehicles = Vehicle::query()
->with([
'vehicle_make_and_model_fk' => function ($query) use ($search) {
$query->where('make', 'like', "%$search%")
->orWhere('model', 'like', "%$search%");
}
])
->where(function ($query) use ($search) {
$query->where('plate', 'like', "%$search%")
->orWhere('vin', 'like', "%$search%");
})
->limit(5)
->get();
Eloquent Relationships - Constraining Eager Loads
$vehicles = Vehicle::where('plate','LIKE','%'.$search.'%')
->orWhere('vin','LIKE','%'.$search.'%')
->with('vehicle_make_and_model_fk')
->orwhereHas('vehicle_make_and_model_fk',
function($query) use($search){
$query
->where('vehicle_make_and_models.make','like',$search.'%')
->orWhere('vehicle_make_and_models.model','LIKE','%'.$search.'%');
}
)
->limit(5)
->get();
This query worked. It would search and bring results from vehicle table and would go to makes and models table and bring results from there as well. Based on - Laravel Eloquent search inside related table

Select User by Profile name in Laravel way

I have models User and Profile with hasOne relationship as following:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class, 'user_id');
}
}
I want to select all users by full_name attribute of Profile in Laravel way. I have tried to this code but it return all the users in user table.
User::with(['profile' => function ($q) use ($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
}]);
Any idea? Thanks so much.
Try whereHas method like:
User::whereHas('profile', function($q) use($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
});

How to group where clauses in Laravel Query Builder correctly

I am running the following query using the search() function below - the problem is I need to group the where clauses - what am I doing wrong?
select `standings`.*, `users`.`name` as `user` from `standings`
left join `users` on `standings`.`user_id` = `users`.`id`
where `users`.`name` like '%bob%' or `users`.`email` like '%bob%'
and `standings`.`tenant_id` = '1'
In my Standings model I have the following search() that performs the WHERE clause
public static function search($query)
{
return empty($query) ? static::query()
: static::where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
}
public function render()
{
$query = Standing::search($this->search)
->select('standings.*', 'users.name AS user')
->leftJoin('users', 'standings.user_id', '=', 'users.id')
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('standings.tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}
The query works however it doesn't group the WHERE clause correctly on the users.name & users.email fields - how do I change this search() function so the WHERE query has them grouped like this
where (`users`.`name` like '%bob%' or `users`.`email` like '%bob%')`
You need to group the where clauses in a wrapping where clause. Try this
public static function search($query)
{
return empty($query)
? static::query()
: static::where(function($query){
$query->where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
});
}
Thanks that for some reason even though looks correct gives me the following error - Object of class Illuminate\Database\Eloquent\Builder could not be converted to string NB I am using Laravel with Livewire (not sure if that should make any difference)
$query->where('users.name', 'like', '%'.$query.'%') and ->orWhere('users.email', 'like', '%'.$query.'%'); is giving the error because while trying to compare $query is being treated as a string hence the error
You can define the search as a query scope on the model
//Assuming a relation Standing belongsTo User
//Query constraint to get all Standing records where
//related User record's name or email are like searchTerm
public function scopeSearch($query, string $searchTerm)
{
return $query->whereHas('user', function($query) use($searchTerm){
$query->where('name', 'like', "%{$searchTerm)%")
->orWhere('email', 'like', "%{$searchTerm}%");
});
}
Laravel docs:https://laravel.com/docs/8.x/eloquent#local-scopes
With the above search scope defined on Standing model, you can have the render function as
public function render()
{
$query = Standing::with('user:id,name')
->search($this->search)
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}

How to search a term in eloquent relation of a model?

There is a Model named Profile that has user relation.
public function user(){
return $this->belongsTo(User::class);
}
and the profile table column is:
id | user_id | image | tel
The question is how I can search the name of a user from profile?
$term = request()->term;
$profiles = Profile::with('user')->where('name', 'like', '%'.$term.'%')->get();
Then I want to show the profiles that their name comes from the search term.
use whereHas() ref link https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence
$term = request()->term;
$profiles = Profile::whereHas('user',function($q) use($term){
$q->where('name', 'like', '%' . $term . '%');
})->get();
$filterUser = function ($q) use ($term) {
$q->where('name', 'like', '%' . $term. '%');
};
$term = request()->term;
$profiles = Profile::whereHas('user', $filterUser)->with(['user'=> $filterUser])->get();
If you want to syntactically optimize the code and want to use this more often then add this method in model
public function scopeWithAndWhereHas($query, $relation, $constraint){
return $query->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}
And Usage:
$term = request()->term;
$profiles = Profile::withAndWhereHas('user', function($q) use ($term){
$q->where('name', 'like', '%' . $term. '%');
})->get();
You need to scope it on the subquery, something like this:
$profiles = Profile::with(['user' => function ($query) {
$query->where('name', 'like', '%'.$term.'%');
}])->get();

How to search an item by category and location in laravel simultaneously

The items have category_id and location_id which has relation to tables category and location.
The search form has 3 fields, 1 item keyword, 2nd is the category selection and 3rd is its location.
The user has to fill all the fields in order to be able to search.
The problem is that the search works only for the first input field and brings all the items with the same name but location and categories are not filtered during search...
public function search(Request $request) {
$query = $request->input('query');
$cQuery = $request->input('subCategoryId');
$pQuery = $request->input('province');
$subCategories = Business::where('name', 'like', "%$query%")
->where('province_id', 'like', "%$pQuery%")
->where('sub_category_id', 'like', "%$cQuery%")->get();
return view('pages.search-result')
->with('subCategories', $subCategories);
}
I have assumed that you have the relations setup for all the models. If not, please go through Defining Relationships.
Consider the below answer as a skeleton example for what you are looking for.
$businesses = Business::where('name', 'like', '%' . $query . '%')
->with('province', 'subCategory')
->whereHas('province', function ($q) use ($pQuery) {
$q->where('name', 'like', '%' . $pQuery . '%');
})
->whereHas('subCategory', function ($q) use ($cQuery) {
$q->where('name', 'like', '%' . $cQuery . '%');
})
->get();

Resources