Reputation: 164
A user has a sponsor:
public function sponsor()
{
return $this->belongsTo(User::class, 'sponsor_id');
}
A user has referrals:
public function referrals()
{
return $this->hasMany(User::class, 'sponsor_id');
}
A user is considered capped when they have 2 or more referrals:
public function activeReferrals()
{
return $this->referrals()->whereActive(true);
}
public function isCapped()
{
return $this->activeReferrals()->count() >= 2;
}
A user can give points. By default, the sponsor will receive them, but if the sponsor is capped, I want the points to go to a sponsor's referral that is NOT capped. If all the referrals are capped, then it does the same thing with the level below (the referral's referrals).
If I go user by user making database calls for each one, it's gonna take a long time. How can I write a scope that makes recursive calls until it finds the first active referral in the tree that's not capped?
This is what I'm trying to do:
Upvotes: 0
Views: 374
Reputation: 3572
Please give this a try... I believe this will work for you :)
public function scopeNotCappedActiveReferrals($query, $count) {
return $query->withCount(['referrals' => function($q) {
$q->where('active', true);
}])->where('referrals_count', '<', $count);
}
For the second part...
// Finally you can call it with
public function allReferrals() {
$users = User::notCappedActiveReferrals(2)->get();
$allUsers = $this->findNotCappedActiveReferralsRecurrsively($users);
}
// Do not place this function in the model,
// place it in your Controller or Service or Repo or blahblah...
// Also, not tested... but should work :)
protected function findNotCappedActiveReferralsRecurrsively($users) {
if(!count($user)) {
return $users;
}
foreach($users as $user) {
$moreUsers = $user->notCappedActiveReferrals(2)->get();
return $users->merge($this->findNotCappedActiveReferralsRecurrsively($moreUsers));
}
}
Hope this is what you need :)
Upvotes: 1