2016-12-21 5 views
0

ich einen Bericht bin Modellierung, die von seinem Typ abhängig (Person fehlt, wollte, usw.) könnten verschiedene Felder enthalten, aber jede Art teilt sich eine Anzahl von Feldern. Dies ist, denke ich, was unterscheidet diese Frage von sagen: this question, wo die Felder über alle Arten hinweg sind.Laravel Eloquent polymorphe Beziehungen modellieren Hierarchie/Vererbung

Im Moment habe ich seine Art ein Berichtsmodell mit einem ganzzahligen Feld angelegt habe angibt, die eine Art Tabelle verweist. Der Vorteil ist, dass dies ein einfaches Modell zu verstehen und zu implementieren ist. Es bedeutet, dass ich auch leicht nach Objekten suchen kann. Auf der anderen Seite bedeutet dies, dass einige Felder für einige Modelle nicht sinnvoll sind und daher immer Null sind. Wenn ich Felder für die einzelnen Typen hinzufüge, habe ich viele Spalten in der Tabelle, von denen viele null sind.

würde ich eine Beratung auf Laravel der (5.2) polymorphe Beziehungen verwenden. Die Art, wie ich mir das vorstelle, ist, dass ich ein Basisreportmodell haben werde, das alle geteilten Felder enthält und die MorphTo Felder hat; Dann trennen Sie die verschiedenen Typen mit ihren eindeutigen Feldern in einer Eins-zu-Eins-Beziehung mit dem Berichtsmodell. Ist das möglich und macht das überhaupt Sinn? Die Probleme, die ich sehe, sind, dass ich die Fähigkeit verliere, über alle "Berichte" unabhängig vom Typ zu suchen. Oder gibt es einen Weg darum, sagen wir Java, wo die Vererbung es zulässt, dass Unterklassen als Mitglieder der Oberklasse betrachtet werden?

Eine grobe Schema solcher Beziehungen ist unten dargestellt. Reports enthält die freigegebenen Felder, während Wanted und Missing eindeutige Felder haben.

Relationship between wanted and missing reports, and the base report

Antwort

0

Aus dem Diagramm über die Beziehungen in Ihrer Frage darstellt, halte ich es für einen straight forward Fall von Elternteil - Kind. Hier

, Ihre BaseReport oder Report ist das Muttermodell so zu sagen, und die WantedReport und MissingReport sind das Kind - so zu sagen.

Die einzige Sache, die in Ihrem Diagramm geändert werden muss, ist, dass Sie den Fremdschlüssel report_id in Ihren untergeordneten Tabellen definieren müssen, um auf den übergeordneten Datensatz in der Basisberichtstabelle zu verweisen.

Table-reports 
id // primary key 
date 
description 

Table - wanted_reports 
id //primary key 
report_id //foreign key linking to the reports table 
status_at 
is_captured //maybe a boolean field 
charge 

Table - missing_reports 
id //primary key 
report_id  //foreign key linking to the reports table 
status_at 
is_found 
last_seen_date 
last_seen_at 

Das können Sie die entsprechenden Modelle definieren - Bericht

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class Report extends Model 
{ 
    protected $table = 'reports'; 

    protected $fillable = ['report_date', 'description']; 

    public function wanted_reports() 
    { 
     return $this->hasMany(WantedReport::class); 
    } 

    public function missing_reports() 
    { 
     return $this->hasMany(MissingReport::class); 
    } 
} 

WantedReport

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class WantedReport extends Model 
{ 

    protected $table = 'wanted_reports'; 

    protected $fillable = ['report_id', 'status_at', 'is_captured', 'charge']; 


    public function report() 
    { 
     return $this->belongsTo(Report::class); 
    } 
} 

MissingReport

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class MissingReport extends Model 
{ 

    protected $table = 'missing_reports'; 

    protected $fillable = ['report_id', 'status_at', 'is_found', 'last_seen_date', 'last_seen_at]; 


    public function report() 
    { 
     return $this->belongsTo(Report::class); 
    } 
} 

dann überall in der Anwendung, um die Beziehungen zugreifen können, wie Sie es normalerweise tun, zum Beispiel

<?php 

namespace App\Http\Controllers; 

use Illuminate\Http\Request; 

class ReportsController 
{ 

    public function store(Request $$request) 
    { 
     $report = $this->model->create([ 
      'report_date' => Carbon:::now(), 
      'description' => $request->get('description') 
     ]); 

     if($report) 
     { 
      $wantedReport = $report->wanted_reports()->create([ 
       'status_at' => $request->get('status'), 
       ... 
      ]); 

      $missingReport = $report->missing_reports()->create([ 
       'status_at' => $request->get('status'), 
       ... 
      ]); 
     } 

    } 
} 

hoffe, das hilft

+0

Dank @Donkamash. Dies ist sehr sinnvoll und sehr prägnant. Wie auch immer, jeder wanted_report und missing_report bezieht sich nur auf einen Bericht, also bin ich mir nicht sicher, ob das richtig ist?'public function missing_reports() { Rückgabe $ this-> hasMany (MissingReport :: class); } 'Ich habe auch immer noch Schwierigkeiten herauszufinden, warum nicht eine polymorphe Beziehung. Soweit ich sagen kann polymorph beseitigt die Notwendigkeit, den Fremdschlüssel explizit zu pflegen. Ich wickle immer noch meinen Kopf um diese Konzepte, also ertragen Sie mit mir –

+0

Wenn es eine Eins-zu-Eins-Beziehung ist, dann können Sie Ihre Beziehung entsprechend definieren 'public function missing_reports() {return $ this-> hasOne (MissingReport :: class); } '. Ihr Fall erfordert keine polymorphe Relation und denken Sie auch daran, dass eine polymorphe Relation eine zusätzliche Tabellensuche während der Abfrage erfordert (Leistungseinfluss). Verwenden Sie sie also nicht, wenn sie nicht benötigt wird - ich würde vorschlagen. Aber wieder kommt es auf Ihre Präferenz an. – Donkarnash

+0

Danke. Lass mich das umsetzen. Ich neige dazu, Ihre Antwort zu akzeptieren, aber lassen Sie mich zuerst bestätigen, dass es in der Praxis so funktioniert, wie ich es möchte. –

Verwandte Themen