首页 > 解决方案 > 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

标签: phplaravel

解决方案


IMPORTANT: as per my comments under the question, this answer is to emphasize 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 to the website
  • B refers C to the website
  • C refers D to the website
  • D refers E to the website, and
  • E refers F to the website

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;

$referralsOfC = 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.


推荐阅读