Optimieren Sie Laravel Join, um alle Daten in einer einzelnen Zeile abzurufen, ohne Tabellen zu duplizieren
P粉410239819
P粉410239819 2024-01-16 11:40:46
0
1
473

Ich habe 4 MySQL-Tabellen und verwende PHP und Laravel 7

  1. Mitglieder
  2. Abzug
  3. Zahlung
  4. Zahlungsabzüge

Jetzt möchte ich die Einzelzahlung und alle anderen Abzüge jedes Mitglieds fortlaufend anzeigen. (Angenommen, eine Person hat nur eine Zahlung)

Die Datenbankstruktur ist wie folgt

Dies ist die HTML-Tabelle, die ich anzeigen möchte

Dies ist die Abfrage, die ich verwende, aber sie dupliziert die Daten.

$payments = Payment::leftJoin('members', 'payments.member_id', '=', 'members.id')
        ->leftJoin('payment_deductions', 'payments.id', '=', 'payment_deductions.payment_id')
        ->leftJoin('deductions', 'payment_deductions.deduction_id', '=', 'deductions.id')
        ->select(
            'members.*',
            'payment_deductions.*',
        )
        ->orderBy("member_id", "ASC")
        ->get()->toArray();

Das resultierende Array wiederholt jedes Mitglied basierend auf seiner Ableitung.

Gibt es eine Möglichkeit, diese Daten zu verbessern? So etwas wie eine verschachtelte Reihe von Abzügen für jedes Mitglied?

Das ist das Modell

Mitglied

namespace App;

    use IlluminateDatabaseEloquentModel;
    use CarbonCarbon;

    class Member extends Model
    {
        protected $fillable = [
            'full_name',
            'email',
            'created_by',
        ];
    }

Zahlung

namespace App;

    use IlluminateDatabaseEloquentModel;

    class Payment extends Model
    {
        protected $fillable = [
            'member_id',
            'total_amount',
            'payable_amount',
            'created_by',
        ];

        public function deductions() {
           return $this->belongsToMany(Deduction::class,'payment_deductions')->withTimestamps();
        }
    }

Abzug

namespace App;

    use IlluminateDatabaseEloquentModel;

    class Deduction extends Model
    {
        protected $fillable = [
        'title',
        'priority',
        'created_by',
        ];
    }


P粉410239819
P粉410239819

Antworte allen(1)
P粉239089443

在构建模型时,您非常接近并且处于正确的轨道上,您缺少的是如何在不创建另一个查询的情况下加载关系,如果您查看控制器,您将看到加载内部关系的标准方法。希望这是一个更好的概念来解决您的担忧。

供参考:https://laravel.com/ docs/9.x/eloquent-relationships#lazy-eager-loading

这样做也可以避免将来的 N+1 问题,请参阅什么是 ORM(对象关系映射)中的“N+1 选择问题”? 有关 N+1 的详细信息

会员模型

public class Member extends Model
{
    protected $fillable = [
       'full_name',
       'email',
       'created_by',
    ];
        
    public function payments(){
        return $this->hasMany(Payment::class);
    }
}

支付模式

public class Payment extends Model
{
    protected $fillable = [
       'member_id',
       'total_amount',
       'payable_amount',
       'created_by',
    ];
        
    public function member(){
        return $this->belongsTo(Member::class);
    }

    public function deductions() {
        return $this->belongsToMany(Deduction::class,'payment_deductions')->withTimestamps();
    }
}

推演模型

public class Deduction extends Model
{
    protected $fillable = [
       'title',
       'priority',
       'created_by',
    ];
        
    public function payments() {
        return $this->belongsToMany(Payment::class,'payment_deductions')->withTimestamps();
    }
}

成员控制器:

/**
 * Show the specified model.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  Member $member
 * @return \Illuminate\Http\Response
 */
public function show(Request $request, Member $member){
    // This will load all of the inner relationships in a single query.
    $member->load('payments.deductions');
        
    //Assign the loaded payments to be used
    $payments = $member->payments;
        
    /* 
        You can acess the payments -> deductions in a foreach loop, in php or blade
        foreach($payments->deductions as $deduction){
           //$deduction->id   
        }
    */  
        
    return view('sampleView', compact('member', 'payments'));
}
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage