How to loop multiple nested loop in one table in laravel?

I have referral commission details and different levels of referral users I need to show that in the table with there are levels. Here I did coded but I’m not satisfied with the logic please let me know the logic is correct or wrong you see the below images for reference.

What i’m looking for

Image

Here my table

Table image

What i did so far

Controller

  public function inDirectCommission()
  {

    $user =  User::where('id', 1)->first();
    $user_id = $user->id;

    $direct_commissions = Referral::where('parent_id', $user_id)->get();

    foreach ($direct_commissions as $row) {
      $second_level = Referral::where('parent_id', $row->user_id)->get();
      foreach ($second_level as $row) {
        $third_level = Referral::where('parent_id', $row->user_id)->get();
        foreach ($third_level as $row) {
          $forth_level = Referral::where('parent_id', $row->user_id)->get();
          foreach ($forth_level as $row) {
            $fifth_level = Referral::where('parent_id', $row->user_id)->get();
            foreach ($fifth_level as $row) {
            }
          }
        }
      }
    }

    return view('site.user.dashboard.commission.in_direct_commission', compact('second_level', 'third_level', 'forth_level', 'fifth_level'));
  }

Blade

<table id="example1"
   class="table table-bordered table-striped dataTable dtr-inline direct-table"
   role="grid" aria-describedby="example1_info">
   <thead>
      <tr>
         <th>Date</th>
         <th>Referal</th>
         <th>Level</th>
         <th>Amount</th>
      </tr>
   </thead>
   <tbody>
      @foreach ($second_level as $row)
      <tr>
         <td>{{ $row->created_at }}</td>
         <td>{{ $row->user->name }}</td>
         <td>2<sup>nd</sup> Level</td>
         <td>4000</td>
      </tr>
      @endforeach
      @foreach ($third_level as $row)
      <tr>
         <td>{{ $row->created_at }}</td>
         <td>{{ $row->user->name }}</td>
         <td>3rd<sup>rd</sup> Level</td>
         <td>3000</td>
      </tr>
      @endforeach
      @foreach ($forth_level as $row)
      <tr>
         <td>{{ $row->created_at }}</td>
         <td>{{ $row->user->name }}</td>
         <td>4<sup>th</sup> Level</td>
         <td>2000</td>
      </tr>
      @endforeach
      @foreach ($fifth_level as $row)
      <tr>
         <td>{{ $row->created_at }}</td>
         <td>{{ $row->user->name }}</td>
         <td>5<sup>th</sup> Level</td>
         <td>1000</td>
      </tr>
      @endforeach
   </tbody>
</table>

dd of second level user

Collection dump

Answer

IMPORTANT: As per my comments under the question, this answer is to emphasis the idea only. Code samples and concepts might need to be adjusted to match your needs.

Assume there are users A,B,C,D,E and F and each has ids 1,2,3,4,5 and 6 respectively. Also let’s assume ‘A’ was a directly registered user. And:

  • A refers B
  • B refers C
  • C refers D
  • D refers E, and
  • E refers F

With each user record, you can store their referral chain (ref_chain) in the database. At the time of user registration you can do this.

$a->ref_chain = null; // because he hasn't been referred by anyone
$b->ref_chain = '1';  // B (id = 2) is a direct referral of A (id = 1)
$c->ref_chain = '2-1'; // C (id = 3) is a direct referral of B (id = 2)
$d->ref_chain = '3-2-1'; // D (id = 4) is a direct referral of C (id = 3)

// similarly

$e->ref_chain = '4-3-2-1';
$f->ref_chain = '5-4-3-2-1';

Here, what you do is, at the time of registration you get the referring user’s ref_chain and attach referring user’s id to to the beginning of the string with a hyphen. For an example if we consider the time of C’s registration:

$referringUser = $b;
$c->ref_chain = $b->id.'-'.$b->ref_chain;

Now consider the scenario where you want to get the referrals of C.

What you have to do is search in the ref_chain column in the database using the SQL like keyword;

$refferalsOfC = User::where('ref_chain','like',$c->id.'-%')
                      ->orWhere('ref_chain','like','%-'.$c->id.'-%')
                      ->orWhere('ref_chain','like','%-'.$c->id)
                      ->orWhere('ref_chain',"$c->id")
                      ->get();

After that, you can loop through the collection and display the result as you please. Depending on the position of C’s id in the ref_chain attribute you can recognize which level the referral is in.

This way you can drastically reduce the number of database queries and traversal.

Hope you can understand.

Leave a Reply

Your email address will not be published. Required fields are marked *