Laravel whereHas Filter sub relation - laravel

Is that any method to filter the employees and the manpower table record does not return also?
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower.employees', function ($q) {
$q->where('status', 1);
})
->get();
Pwra Class
public function manpower()
{
return $this->hasMany('App\Models\Manpower', 'pwra_uuid', 'pwra_uuid');
}
Manpower Class
public function employee()
{
return $this->hasOne('App\Models\Employees', 'employees_uuid', 'employees_uuid')->where('status', 1);
}
What I expected is: When the employees Status = 0, it will not return any record even manpower.

you can try 2 level whereHas()
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower', function ($q) {
$q->whereHas('employees',function($subQ){
$subQ->where('status', 1);
});
})
->get();
whereHas('manpower.employees' it will not work

Related

Laravel How to get `->sum('count')` in `whereHas` subquery?

I have 3 model Transaction , Cart , Acceptedcart.
in Cart model I have transaction_id and in Acceptedcart model have cart_id.
in Transaction.php my relationship to carts:
public function carts()
{
return $this->hasMany(Cart::class);
}
in Cart.php my relationship to accepted carts :
public function accepted_carts()
{
return $this->hasMany(Acceptedcart::class);
}
And the query to get the transactions where acceptedcart->sended== false:
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false);
})->get();
Now I want to get sum() of count column in acceptedcart, where I can set the sum()?
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false);
})->sum('count);
Or
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false)->sum('count');
})->get();
is there Only one way that foreach on the ->get() result ?
Try this
Transaction.php
public function accepted_carts()
{
return $this->hasManyThrough(Acceptedcart::class, Cart::class);
}
Query
$transactions = Transaction::query()
->whereHas('accepted_carts', fn ($query) => $query->where('sended', false))
->withCount([
'accepted_carts' => fn ($query) => $query->select(DB::raw('SUM(count) as accepted_carts_sum'))
])
->get();

Call to a member function addEagerConstraints() on null, custom key in model Laravel

I'm refactoring a personal Laravel project and I got blocked in the way of improving it.
The function worked this way:
1. Get a collection from the model Thread
2. A foreach loop checks if a User voted that very thread, adding a custom key->value
3. Return the collection
What I had working up until now, was this:
ThreadController:
$threads = Thread::orderBy('created_at', 'desc')
->with('communities')
->with('author')
->withCount('replies')
->withCount('upvotes')
->withCount('downvotes')
->paginate(4);
foreach ($threads as $thread) {
if (Auth::user()) {
if (Vote::where('user_id', '=', Auth::user()->id)->where('thread_id', '=', $thread->id)->where('vote_type', '=', 1)->exists()) {
$thread->user_has_voted = 'true';
$thread->user_vote_type = 1;
} elseif (Vote::where('user_id', '=', Auth::user()->id)->where('thread_id', '=', $thread->id)->where('vote_type', '=', 0)->exists()) {
$thread->user_has_voted = 'true';
$thread->user_vote_type = 0;
} else {
$thread->user_has_voted = 'false';
}
}
}
return $threads;
What I would like to do is something like this:
Thread Model:
public function userVoteThread() {
if (Vote::where('user_id', '=', Auth::user()->id)
->where('thread_id', '=', $this->id)
->where('vote_type', '=', 1)
->exists()) {
return $this->user_vote_type = 1;
} elseif (Vote::where('user_id', '=', Auth::user()->id)
->where('thread_id', '=', $this->id)
->where('vote_type', '=', 0)
->exists()) {
return $this->user_vote_type = 0;
}
}
ThreadController:
$threads = Thread::orderBy('created_at', 'desc')
->with('communities')
->with('author')
->with('userVoteThread') <----- ADDING NEW MODEL FUNCTION
->withCount('replies')
->withCount('upvotes')
->withCount('downvotes')
->paginate(4);
After all, the closest I got was this error Call to a member function addEagerConstraints() on null, and I'm stuck trying to improve the code.
Is there a way to make that Thread model function work and use it through the collection?
Thank you very much!
PS: I hope I made myself understood, otherwise, ask me about it. Thank you :D
Firstly add relationship to the Thread model.
class Thread {
public function votes() {
return $this->hasMany(Thread::class);
}
}
Add your Eloquent Accessor to the Thread.
class Thread {
public function getUserVoteTypeAttribute() {
$this->votes
->where('user_id', Auth::user()->id ?? -1)
->first()->user_vote_type ?? null;
}
public function getUserHasVotedAttribute() {
return $this->user_vote_type !== null;
}
}
Now you can access these attributes on your model.
$thread = Thread::with('votes')->find(1);
$thread->user_vote_type;
$thread->user_has_voted;

Laravel WhereHas Query

I wanna get data which is pwra_dt = $month && $year. What can I do? For now, it shows all records!!
Query:
$purchaseOrder = PurchaseOrder::whereHas('pwra', function (Builder $query) use ($year, $month) {
$query->whereYear('pwra_dt', $year)
->whereMonth('pwra_dt', $month);
})
->get();
PurchaseOrder(Model)
public function pwra()
{
return $this->hasMany('App\Models\Pwra', 'purchase_order_uuid', 'purchase_order_uuid');
}
PWRA (Model)
public function purchaseOrder()
{
return $this->belongsTo('App\Models\PurchaseOrder', 'purchase_order_uuid', 'purchase_order_uuid');
}

How can I combine both of these conditions? in laravel

I'am new with laravel. How can I combine both of these conditions?
public function student($classroom_id)
{
$members = Classroom::findOrFail($classroom_id,)->members->load('role');
$members = User::where([
['role_id', 2]
])->get();
return response()->json($members);
}
Try this:
public function student($classroom_id)
{
$members = Classroom::whereHas('members.role', function ($query) {
$query->where('id', '2');
})->findOrFail($classroom_id)->members->load('role');
return response()->json($members);
}

How to do join table by ID as primary key in query -laravel

I want to do a function where filter based on 2 database tables. However, Im not sure how to put the join table in the query. Which means the data will be filtered from two table (user and employee tables) before returning the result to the datatable.
My filter query is
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
$query = user::query();
if(!empty($request->age)){
$query->where('age','>=',$age );
}
if(!empty($request->gender)){
$query->where('gender','<=',$gender);
}
$data = $query->get();
return datatables()->of($data)->make(true);
}
The table that I want to join in the query is from table employee (column = income and house_ownership) .and the primary key that connect both tables is IC.
If you have relationship in both model, you can use whereHas:
if(!empty($request->income) || !empty($request->house_ownership)){
$query->whereHas('employee', function($q) use ($income, house_ownership) {
if (!empty($income)) {
$q->where('income', $income);
}
if (!empty($house_ownership)) {
$q->where('house_ownership', $house_ownership);
}
});
}
...
Or you can just use join or leftjoin to filter another table:
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
$house_ownership = $request->house_ownership;
$income= $request->income;
$query = user::query();
$query->leftjoin('employee', 'employee.IC', '=', 'user.IC');
if(!empty($request->age)){
$query->where('user.age','>=',$age );
}
if(!empty($request->gender)){
$query->where('user.gender','<=',$gender);
}
if(!empty($request->income)){
$query->where('employee.income', $income);
}
if(!empty($request->house_ownership)){
$query->where('employee.house_ownership', $house_ownership);
}
$data = $query->select('user.*')->get();
return datatables()->of($data)->make(true);
}
Try This
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
if(!empty($request->age)){
$data = User::where('age','>=',$age)->get();
}
if(!empty($request->gender)){
$data = User::where('gender','<=',$gender)->get();
}
return datatables()->of($data)->make(true);
}
You can use Eloquent::when() to reduce if-else for Conditional Queries.
public function filterQuery(Request $request){
$query = user::query();
$query->select('user.*')->join('employee', 'employee.IC', '=', 'user.IC');
$data = $query
->when(request('age') != null , function ($q) {
return $query->where('user.age','>=',request('age'));
})
->when(request('gender') != null , function ($q) {
return $query->where('user.gender','<=',request('gender'));
})
->when(request('income') != null , function ($q) {
return $query->where('employee.income','<=',request('income'));
})
->when(request('house_ownership') != null , function ($q) {
return $query->where('employee.house_ownership','<=',request('house_ownership'));
})
->get();
return datatables()->of($data)->make(true);
}

Resources