Laravel Eloquent making select on whereHas() - laravel

How can I select on whereHas() some columns in relation.
My current query looks like as it follows
Location::select(['title'])
->withCount(['job' => function($q) {
return $q->where('language_id', 1)->whereNull('deleted_at');
}])->whereHas('country', function ($q) {
return $q->where('id', '=', 80);
})->get();
and I tried
Location::select(['title', 'id as value'])->withCount(['job' => function($q) {
return $q->where('language_id', 1)->whereNull('deleted_at');
}])->whereHas('country', function ($q) {
return $q->select('title', 'iso3')->where('id', '=', 80);
})->get();
but nothing is getting returned on country relation. How do I refactor this query to get it work?

whereHas() doesn't eager load the relation, only filters results based on it. To eager load, use with().
Location::with('country:id,title,iso3')
->select(['title', 'id as value', 'country_id'])
->withCount(['job' => function($q) {
$q->where('language_id', 1)->whereNull('deleted_at');
}])
->whereHas('country', function ($q) {
$q->where('id', '=', 80);
})->get();

Related

Pluck the values from WITH Eloquent in Laravel

I have a dropdown box that shows only the user with collector and borrower's role. Here's my code
public function create()
{
$users = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector')->orWhere('roles.name', '=', 'borrower');
})
->with('profile')
->get()
->pluck('name','id');
return view('dashboard.documents.create', compact('users'));
}
this code is fine but what I what to pluck is the column first_name, last_name and user_id from 'profile'.
How can I achieve that?
Thank you so much in advance!
You do one of these
$users = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector')->orWhere('roles.name', '=', 'borrower');})
->with('profile')
->select('name','id')
->get();
Or
$users = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector')->orWhere('roles.name', '=', 'borrower');})
->with('profile')
->get(['name','id']);
Both ways will return a collection with related models each model record will has the selected columns, if you want to convert it to an array you can add ->toArray() after the two ways and it will convert the collection to array.

Orderby Desc in Eloquent, Laravel

I have a query 3 tables are joined together, I want to order the results in Descending order from created_at in messages table, please help. Thank you.
controller:
return new AllChats(Chat::latest('created_at')->whereHas('messages')->with(['messages.users', 'users' =>
function ($query) {
$query->where('id', '!=', Auth::id());
}])->whereHas('users', function ($query) {
$query->where('id', '=', Auth::id());
})->get());
Display the results in desc order but from messages.created_at??
You need to just add the ->orderBy on your created at field in your query.
return new AllChats(Chat::latest('created_at')->whereHas('messages')->with(['messages.users',
'users' => function ($query) {
$query->where('id', '!=', Auth::id());
}])
->orderBy('created_at', 'desc')
->whereHas('users', function ($query) {
$query->where('id', '=', Auth::id());
})->get());
Reference: https://laravel.com/docs/5.7/eloquent
use like this
return new AllChats(Chat::latest('created_at')>>whereHas('messages',function($q){
$q->orderBy('created_at', 'desc');
})->with(['messages.users', 'users' =>
function ($query) {
$query->where('id', '!=', Auth::id());
}])->whereHas('users', function ($query) {
$query->where('id', '=', Auth::id());
})->get());
You can use a modified withCount():
$chats = Chat::withCount(['messages as latest_message' => function($query) {
$query->select(DB::raw('max(created_at)'));
}])
->orderByDesc('latest_message')
[...]
->get();

How to use whereHas for ignoring empty array in eager loading

I don't know how to ignore empty array values in my case. In my query I'm eager loading messages, but it gives me
messages => []
with my query when deleted_from_sender is set to 1 (but I want to ignore it for pagination)
static::with(['messages' => function ($q) use ($id) {
return $q->where(function ($q) use ($id) {
$q->where('user_id', $id)
->where('deleted_from_sender', 0);
})
->orWhere(function ($q) use ($id) {
$q->where('user_id', '!=', $id);
$q->where('deleted_from_receiver', 0);
})->latest();
}])->get();
I tried has and whereHas with the same query and whereNotNull, but no luck.

How to use where conditional in with Laravel?

I do request using query:
return Baber::where(function ($query) use ($request) {
// HERE CONDITION WHERE FOR USER TABLE
})->with("user")->orderBy('id', 'desc')->get();
How can I use where() inside query, that it will be comparabled with user table in with("user")?
I mean the following:
return Baber::where(function ($query) use ($request) {
$query->where('user.created_at', $request->date);
})->with("user")->orderBy('id', 'desc')->get();
It's known as constraining eager loads.
Baber::with(['user' => function ($query) use ($request) {
$query->where('user.created_at', '=', $request->date);
}])
->orderBy('id', 'desc')
->get();

Laravel: whereHas->WhereHas->Where query. Need to add wherePivot

I am selecting all the ScheduledPrograms from a certain data range that has Attendees that belong to a certain User. I want to add a filter to select only the SchduledPrograms where the pivot field registered=1
I.E. I need to add a wherePivot('registered', 1) for the many-to-many relation scheduledPrograms->attendees. I How do I do this? My mind is scrambled from all the where clauses.
$programs = ScheduledProgram::where('registration_start_date', '<=', $today)
->where('end_date', '>=', $today)
->whereHas('attendees', function($q) use($user)
{
$q->whereHas('user', function($q) use($user){
$q->where('id', $user->id);
});
})->get();
Models
Attendee->belongsTo('User')
->belongsToMany('ScheduledPrograms')
User->hasMany('Attendee')
ScheduledProgram->belongsToMany('Attendee')
`
ScheduledProgram Model
public function attendees()
{
return $this->belongsToMany('Attendee', 'prog_bookings')->withPivot('registered','paid');
}
wherePivot() can be used only for belongsToMany instances, but whereHas() closure function receives Builder instance instead.
So you can't use wherePivot() inside whereHas().
Method wherePivot works with model instances, not with the Model Query Builder.
I think when using whereHas method, the pivot table is already joined by eloquent, so just start using it in the whereHas method:
$programs = ScheduledProgram::where('registration_start_date', '<=', $today)
->where('end_date', '>=', $today)
->whereHas('attendees', function($q) use($user)
{
$q
//========= See this: =========
->where('prog_bookings.registered', '1')
->whereHas('user', function($q) use($user){
$q->where('id', $user->id);
});
})
->wherePivot('registered', 1)
->get();
did you try anything? What error do you get?
If the 'registered' field is in the pivot table between ScheduledPrograms and Atendees relation, you can add the where clause before the get():
$programs = ScheduledProgram::where('registration_start_date', '<=', $today)
->where('end_date', '>=', $today)
->whereHas('attendees', function($q) use($user)
{
$q->whereHas('user', function($q) use($user){
$q->where('id', $user->id);
});
})
->wherePivot('registered', 1)
->get();

Resources