Laravel Query Through Relationship - laravel

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

Related

Searching with multiple tables in laravel

I have this search query
$products = Product::query()
->where('name', 'LIKE', "%{$search}%")
->orWhere('slug', 'LIKE', "%{$search_any}%")
->where('status', 'Active')
->get();
i have user table which stores the user who listed the product and its relation is as follows
Product Model:
public function user()
{
return $this->belongsTo(User::class);
}
I have one field type in user table, i want if user enters search string matches type also then also all the products added by them should be returned i was trying this code but how can i combine both the queries
$products = Product::query()
->where('name', 'LIKE', "%{$search}%")
->orWhere('slug', 'LIKE', "%{$search_any}%")
->where('status', 'Active')
->get();
$productsAddedByUser = User::where('type', 'LIKE', "%{$search_any}%")->get();
// saved $productsAddedByUser result in this array $userIdarray
$productnew = Product::whereIn('user_id', $userIdarray)->get();
I want to combine both the results of $productnew and $products
At first save result in $userIdarray, then in products query:
$userIdarray = User::where('type', 'LIKE', "%{$search_any}%")->pluck('id');
$products = Product::query()
->where(
fn($query) => $query->where('name', 'LIKE', "%{$search}%")
->orWhere('slug', 'LIKE', "%{$search_any}%")
)
->where('status', 'Active')
->when(count($userIdarray), fn($query) => $query->whereIn('user_id', $userIdarray))
->get();

Laravel how to Order by relation in scope?

I have the following scope in User model
$query->with('country')
->when($filters['search'] ?? null, function ($query, $search) {
return $query->where('name', 'LIKE', '%' . $search . '%')
->orWhereHas('country', function ($query) use ($search) {
$query->where('name', 'LIKE', '%' . $search . '%');
});
});
$query->orderBy('name', 'asc');
}
return $query;
}
I am pretty new to Laravel - I currently the above query is sorting by user name but I would like to sort by country name. I can do this with country_id as there is a relation but not sure how to sort by country name.
Thanks
there are two approaches we can use to order these users by their company. The first is using a join:
$users = User::select('users.*')
->join('countries', 'countries.id', '=', 'users.country_id')
->orderBy('companies.name')
->get();
Here is the generated SQL for this query:
select users.*
from users
inner join countries on countries.id = users.country_id
order by countries.name asc
The second way is using a subquery:
$users = User::orderBy(Country::select('name')
->whereColumn('countries.id', 'users.country_id')
)->get();
And you can see the reference here: ordering database queries by relationship columns in laravel

Laravel - whereHas query not returning correct records

I am currently writing a search query but I'm having issues joining a where with a whereHas
if I wanna search for categories only..
The below query works if I just search for categories solo
$goals = $myGoals
->whereHas('categories', function ($q) use ($search) {
$q->where('name', 'like', "%$search%");
})->paginate(10);
if I wanna search for the title only..
Same as above if I wanna search for the title of goals solo
$goals = $myGoals->where('title', 'like', "%$search%" )->paginate(10);
both of the queries work if I want to search for them individually.
Query attempt
Below is the query I've written to allow a user to search for the title of a goal and the name of a category.
$myGoals = $team->goals();
$goals = $myGoals
->whereHas('categories', function ($q) use ($search) {
$q->where('name', 'like', "%$search%");
})->where('title', 'like', "%$search%" )->paginate(10);
I have tried the above query but the search results return empty when I enter an input. I've also tried swapping the where() to orWhere() which then returns a goal that doesn't belong to the $team model instance but it's a goal record linking to a different Team model id within the pivot table.
Can anyone spot where I am going wrong? thanks
You need to use it all inside where.
$goals = $myGoals->where(function ($query) use ($search){
return $query->whereHas('categories', function ($q) use ($search) {
$q->where('name', 'like', "%$search%");
})->orWhere('title', 'like', "%$search%" );
})->paginate(10);

Where query in both relationships Laravel 7

How can I get all users which names starts with the given string, and also where their city from profile relationship is equal to London?
$users = User::where('name', 'LIKE', "{$searchingName}%")->with('profile')->get();
You may find whereHas very useful:
use Illuminate\Database\Eloquent\Builder;
// Retrieve profiles where the city is like 'London'.
$users = User::where('name', 'LIKE', "{$searchingName}%")
->whereHas('profile', function (Builder $query) {
$query->where('city', 'like', 'London');
})->get();

Laravel eloquent collection query

I am trying to create a search endpoint for one of my pages but i am having a little trouble writing the query for it to get it going
Team Model
public function members()
{
return $this->hasManyThrough('App\User', 'App\Membership', 'team_id', 'id', 'id', 'user_id');
}
**Member(user) Model **
public function skills()
{
return $this->belongsToMany('App\Skill')->withPivot('boosted');
}
if i access the collection via $team->members; it returns the correct team members
Illuminate\Database\Eloquent\Collection {#1507 ▼
#items: array:2 [▼
0 => App\User {#1508 ▶}
1 => App\User {#1509 ▶}
]
}
i have attempted below within my search function but when i dump the query it basically just returns all the team's and every member belonging to them when it should only be returning 2 members that belong to one specific team like the eloquent collection above.
public function search(Team $team, Request $request)
{
$search = $request->get('search');
$members = Team::with('members')->whereHas('members', function ($q) use ($search) {
$q->where('id', 'like', "%$search%");
})->whereHas('members.skills', function ($q) use ($search) {
$q->where('name', 'like', "%$search%");
})->paginate(10);
return view('team.show', compact('team', 'members'));
}
Are you able to do where() directly on the collection like this?
$members = $team->members;
$memberQuery = $members->where('name', 'like', "%$search%")
->orWhere('id', 'like', "%$search%");
the idea is to go through the member relation within the team model then add the abilty to search through specific fields and do a WhereHas on the skills relation within the member(user model) so i can also search for a field within that too.
I am a little lost on the solution to my problem can anyone point me in the right direction?
$members = Team::whereHas('members', function ($q) use ($search) {
$q->where('id', 'like', "%$search%")
->orWhere(function($q) use($search){
$q->whereHas('skills', function($q) use($search){
$q->where('name', 'like', "%$search%");
});
});
})
->with([
'members' => function ($q) use ($search) {
$q->where('id', 'like', "%$search%")
->orWhere(function($q) use($search){
$q->whereHas('skills', function($q) use($search){
$q->where('name', 'like', "%$search%");
});
})
},
'memebers.skills' => function($q) use($search){
$q->where('name', 'like', "%$search%");
}
])
->paginate(10);
whereHas plays the main role, as it will get only those teams who have members, whose id is like $search or their skills have name like $search.
And as we only need to get the members which satisfy the condition, it is being handled in the eager loading(we're eager loading only those particular members whose id is like $search or their skills have name like $search.)
You can refer to this blog. It has explained this kind of approach in detail
https://medium.com/#sander3/laravel-nested-eager-loading-contraints-9742c2dac4b9

Resources