简体   繁体   中英

Laravel Eloquent hasMany filtered by parent table

In my system there are users, each of which has holiday allowances each year.

There are 3 tables (simplified):

users
- id
- name

user_leave_allowances
- id
- user_id
- from
- to
- allowance

user_leave
- id
- user_id
- from
- to
- days

In the UserLeaveAllowance model I have set up the following relationship:

public function leave(){
    return $this->hasMany('App\UserLeave','user_id','user_id');
}

And retrieving the leave allowance by the following:

$leaveAllowance = UserLeaveAllowance::with(['leave'])
->where('user_id',$id)
->get()

This pulls in the full list of leave allowances (user_leave_allowances) for that user along with all the leave they have currently requested (user_leave).

However, the allowances will be for different periods of time, eg 1/1/2017 - 31/12/2017 and leave will be taken out of these periods. So for each leave allowance period I want just the leave that falls within those two dates (from & to), at the moment it just pulls through all the leave for that user into each leave allowance.

I have tried many different ways around it, using the where conditions on the hasMany as such...

public function used(){
    return $this->hasMany('App\UserLeave','user_id','user_id')
->where('from', '>=', 'user_leave_allowances.from')
->where('to', '<=', 'user_leave_allowances.to');
}

and

public function used(){
    return $this->hasMany('App\UserLeave','user_id','user_id')
->whereRaw('user_leave.from >= user_leave_allowances.from')
->whereRaw('user_leave.to <= user_leave_allowances.to');
}

But I just can't figure out a way to get this to work. I'm fairly new to Laravel and trying to get to grips with Eloqent and relationships, I'm sure the answer isn't too far away.

Here's my suggestion:

users - id - name

user_leave_allowances - id - user_id - from - to

user_leave - id - user_leave_allowances_id - from - to

In short relate your leave with your leave allowances rather than the user directly because in essence a leave request is taken out of the allowance not out of the user directly.

class User extends Model {
     public leaveAllowance() {
         return $this->hasMany(UserLeaveAllowance::class);      
     }        
} 

class UserLeaveAllowance {
      public user() { return $this->belongsTo(User::class); }
      public leaveRequests() { 
        return $this->hasMany(UserLeave::class);
      }
}

class UserLeave {
      public allowancePeriod() { 
        return $this->belongsTo(UserLeaveAllowance::class);
      }
} 

Now you can do things like:

UserLeaveAllowance::whereHas("user", function ($q) { 
        return $q->where("id", <user id>); //Allowances for this user
})->leaveRequests() 
->selectRaw("SUM(TIMESTAMPDIFF(DAY, to, from)) as days")
->value("days");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM