using whereNotIn and subquery in query builder (Laravel 8) - laravel

I would like to make a controller function to search for users by name and display only those name that are not already in a project.
here is the SQL query to display users with name containing 'mmm' who are not already in project id = 2:
SELECT `firstname`
FROM `user_details`
WHERE (
`firstname` LIKE "%mmm%" AND `user_id` NOT IN (
SELECT `member_id` FROM `project_members` WHERE `project_members`.`project_id` = 2)
)
and in the query builder (which doesn't work):
$searchResults = DB::table('user_details')
->select('user_details.user_id', 'user_details.firstname', 'user_details.lastname', 'user_details.nickname', 'user_details.status')
->whereNotIn('user_details.user_id', DB::table('project_members')
->select('member_id')
->where('project_id', '=', $request->project_id)
->get()
->toarray()
)
->where('user_details.firstname', 'LIKE', '%'.$request->searchString.'%')
->orWhere('user_details.lastname', 'LIKE', '%'.$request->searchString.'%')
->get();
Do you know where I did wrong? Thank you!

Got it. I just needed ->pluck('member_id') instead of toarray()
And also, where/orWhere must be grouped.
$searchResults = DB::table('user_details')
->select('user_details.user_id', 'user_details.firstname', 'user_details.lastname', 'user_details.nickname', 'user_details.status')
->whereNotIn('user_details.user_id', DB::table('project_members')
->select('member_id')
->where('project_id', '=', $request->project_id)
->get()
->pluck('member_id')
)
->where(function ($query) use ($request) {
$query->where('user_details.firstname', 'LIKE', '%'.$request->searchString.'%')
->orWhere('user_details.lastname', 'LIKE', '%'.$request->searchString.'%')
->orWhere('user_details.nickname', 'LIKE', '%'.$request->searchString.'%');
})
->get();

Related

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 query isn't allowing me to query and where inside orWhere

I have laravel and laravel-livewire. Maybe it's overkill but I wanted to limit results to 10 or so and then have those 10 results filter to new results as the person typed out a name or phone number. The query works perfectly fine if I use just one of the statements. If I get rid of the phone and leave name it works, the same for getting rid of name and leaving phone. But if I have both like below it doesn't work. In the debug bar I see the query and it looks like what it should, but I don't get any results once I start typing.
$customers = DB::table('customers')->where('user_id', auth()->id())
->where(function($query) {
$query->where('phone', 'like', '%'.$this->phone.'%')
->orWhere('name', 'like', '%'.$this->name.'%');
})
->limit(10)
->get();
outputs query in debug bar
select *
from `customers`
where `user_id` = 12
and (`phone` like '%%' or `name` like '%%')
limit 10`
You can try doing it like this
$customers = DB::table('customers')->where('user_id', auth()->id())
->where(function($query) {
$query->when(!is_null($this->phone), function ($q) {
$q->where('phone', 'like', '%'.$this->phone.'%')
})
->when(!is_null($this->name), function ($q) {
$q->where('name', 'like', '%'.$this->name.'%')
});
})
->limit(10)
->get();

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

Sort a result of search in Laravel Eloquent model with relations

I did a search for a Model (Startup), next step is to order results of the search by DESC or ASC (it doesn't matter now)
My current code is:
$startups = Startup::whereHas('category', function ($query) use ($search, $sort_type) {
$query
->where('name', 'like', "%$search%")
->orderBy('name', $sort_type);
})
->orWhere('description', 'LIKE', "%$search%")
->orWhere('url', 'LIKE', "%$search%")
->get();
return StartupResource::collection($startups);
Explanation of the code:
as you see at the beginning I'm using "whereHas" to search also for coincidences in related model - "Category".
then inside of "whereHas" I'm trying to apply 'orderBy('name', $sort_type)' but it doesn't work properly (it doesn't sort by categories)
I know that we can create method in Startup model and sort it inside of the method, but the problem is that I have to pass variables to the method ( $sort_type, $search) and I don't know how to do this
So how to sort Startups model including related Category model by ASC or DESC in my case ?
Thank you guys a lot for any ideas and help!
That's not possible with whereHas(). You can use a JOIN:
$startups = Startup::select('startups.*')
->join('category', 'category.id', '=', 'startups.category_id')
->where('category.name', 'LIKE', "%$search%")
->orWhere('startups.description', 'LIKE', "%$search%")
->orWhere('startups.url', 'LIKE', "%$search%")
->orderBy('category.name', $sort_type)
->get();

laravel join query is not working

I have the next query and I want to get the price_types.name but is not returned:
$projects = Project::with('projectsTask')
->select('projects.*',
'price_types.name as name_type'
)
->where('client_id', $client->id)
->join('price_types', 'tasks.type_list', '=', 'price_types.id')
->orderBy('id')
->get();
Here an image query is retrievng
This on picture "type_list" must be string text
Maybe somebody can help me.
Many thanks!
Try this:
$projects = Project::with('projectsTask')
->where('client_id', $client->id)
->join('price_types', 'tasks.type_list', '=', 'price_types.id')
->orderBy('id')
->get([''projects.*',
'price_types.name as name_type'']);
get method receive as parameter an array with fields that you want.
$projects = Project::join('tasks', 'projects.id', '=', 'tasks.project_id')
->select('tasks.*',
'price_types.name as name_type',
'statuses.name as name_status'
)
->where([['client_id', $client->id], ['tasks.status_type', '!=', 2]])
->join('price_types', 'tasks.type_list', '=', 'price_types.id')
->join('statuses', 'tasks.status_type', '=', 'statuses.type')
->orderBy('tasks.id', 'DESC')
->get();

Resources