Maison > Questions et réponses > le corps du texte
J'ai 4 tables MySQL, utilisant PHP et Laravel 7
Maintenant, je souhaite afficher en continu le paiement unique de chaque membre et toutes les autres déductions. (En supposant qu'une personne n'a qu'un seul paiement)
La structure de la base de données est la suivante
C'est le tableau HTML que je souhaite afficher
C'est la requête que j'utilise, mais elle duplique les données.
$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();
Le tableau résultant répète chaque membre en fonction de sa dérivation.
Existe-t-il un moyen d'améliorer ces données ? Quelque chose comme un tableau imbriqué de déductions pour chaque membre ?
C'est le modèle
Membre
namespace App; use IlluminateDatabaseEloquentModel; use CarbonCarbon; class Member extends Model { protected $fillable = [ 'full_name', 'email', 'created_by', ]; }
Paiement
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(); } }
Déduction
namespace App; use IlluminateDatabaseEloquentModel; class Deduction extends Model { protected $fillable = [ 'title', 'priority', 'created_by', ]; }
P粉2390894432024-01-17 09:20:05
Vous êtes très proche et sur la bonne voie lors de la construction du modèle, ce qui vous manque, c'est comment charger les relations sans créer une autre requête, si vous regardez le contrôleur, vous verrez la manière standard de charger les relations à l'intérieur. J'espère que c'est un meilleur concept pour répondre à vos préoccupations.
Pour référence : https://laravel.com/docs/9.x/eloquent-relationships#lazy-eager-loading
Faire cela évitera également de futurs problèmes N+1
, voir Quel est le "problème de sélection N+1" dans ORM (Object Relational Mapping) ? N+1
问题,请参阅什么是 ORM(对象关系映射)中的“N+1 选择问题”? 有关 N+1
Détails sur N+1
< /p>
Modèle de membre
public class Member extends Model { protected $fillable = [ 'full_name', 'email', 'created_by', ]; public function payments(){ return $this->hasMany(Payment::class); } }
Mode de paiement
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(); } }
Modèle de déduction
public class Deduction extends Model { protected $fillable = [ 'title', 'priority', 'created_by', ]; public function payments() { return $this->belongsToMany(Payment::class,'payment_deductions')->withTimestamps(); } }
Contrôleur membre :
/** * 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')); }