2016-07-18 10 views
0

I 3-Tabellen, eine news Tabelle Geschäft Nachrichten, songs Tabelle speichert Lieder, comments Tabelle speichern Kommentare, eine Nachricht kann viele Kommentare haben, und ein Lied kann auch viele Kommentare, in meinem comments Tisch, Ich verwende item_id, item_type, um zu ermitteln, zu welchem ​​übergeordneten Modell dieser Kommentar gehört. Wenn z. B. item_type='game' and item_id=1 dieser Kommentar zu game Tisch- und Spiel-ID = 1 gehört. Hier sind meine Modellcodes.eloquent belongsTo Beziehungstabelle bestimmt

Song

class Song 
{ 
    public function comment() 
    { 
     return $this->hasMany(Comment::class, 'item_id', 'id')->where('comments.item_type', '=', Comment::SONG_COMMENT_TYPE); 
    } 
} 

Nachrichten

class News 
{ 
    public function comment() 
    { 
     return $this->hasMany(Comment::class, 'item_id', 'id')->where('comments.item_type', '=', Comment::NEWS_COMMENT_TYPE); 
    } 
} 

Kommentar

class Comment 
{ 
    public function song() 
    { 
     return $this->belongsTo(Song::class, 'item_id', 'id'); 
    } 
    public function news() 
    { 
     return $this->belongsTo(News::class, 'item_id', 'id'); 
    } 
} 

Es ist einfach, Kommentare von Song oder News Modell zu bekommen, aber ich weiß nicht, wie das Gegenteil definieren Beziehung, ist es möglich, eine Methode inzu definieren 210 Modell wie:

public function item() 
{ 
    if ($this->item_type == Comment::SONG_COMMENT_TYPE) { 
     return $this->song(); 
    } else { 
     return $this->news(); 
    } 
} 

Oder vielleicht in der falschen Art und Weise ich denke, wie eloquent zu verwenden, um zu bestimmen, welche Tabelle zur Laufzeit verbinden?

+0

Es sieht aus wie Laravel keine Rückseite für polymorphe Beziehung (korrigiert mich wenn ich falsch liege) hat. Ich denke, diese Lösung ist gut für das, was Sie erreichen wollen. –

+0

@ThomasVanderVeen Ich bin immer noch auf der Datenbank Design-Bühne für meine App, haben Sie irgendwelche Ratschläge für mein Problem? – xcaptain

+0

Sie müssen eine Methode für jede Beziehung im 'Kommentar'-Modell definieren, soweit mir bekannt ist. – haakym

Antwort

1

Zur Umsetzung polymorphe Beziehungen Ich denke, Ihre DB soll wie folgt aussehen:

class Comment extends Model 
{ 
    /** 
    * Get all of the owning commentable models. 
    */ 
    public function commentable() 
    { 
     return $this->morphTo(); 
    } 
} 

class News extends Model 
{ 
    /** 
    * Get all of the news' comments. 
    */ 
    public function comments() 
    { 
     return $this->morphMany('App\Comment', 'commentable'); 
    } 
} 

class Song extends Model 
{ 
    /** 
    * Get all of the song's comments. 
    */ 
    public function comments() 
    { 
     return $this->morphMany('App\Comment', 'commentable'); 
    } 
} 

Weiteres hier: https://laravel.com/docs/5.2/eloquent-relationships#polymorphic-relations

+0

danke, es funktioniert für mich, ich dachte nicht zuerst daran, ein polymorphes Modell zu bauen, dachte ich es war eine Beziehung von eins zu vielen. Und ich fand auch einen tollen Beitrag http://www.easylaravelbook.com/blog/2015/01/21/creating-polymorphic-relations-in-laravel-5/ – xcaptain

1
Ihre Beziehungen für jedes Modell

news 
    id 
    ... 

songs 
    id 
    ... 

comments 
    id 
    commentable_id 
    commentable_type 

Dann sollen wie folgt aussehen

Eine einfache Lösung könnte sein, das Nachrichtenmodell als Ausgangspunkt zu verwenden und die Kommentartabelle mit zwei einfachen Stellen zu verbinden.

Ein Beispiel könnte wie folgt aussehen:

// Comment 

public function news() 
{ 

    return News:: 

     select('news.*') // Only select news columns (can be removed) 

     ->join('comments', 'news.id', '=', 'item_id') // Join comments table 

     ->where('item_type', 'news') // Make sure item type is news 

     ->where('comments.id', $this->id) // Get $this as comment 

     ->first(); // Return a single result. Maybe this is unnecessary, you 
        // should test it by removing this. I assume when this 
        // will be removed it will return an array of results, 
        // and that is not what you want. Right? 

} 

Diese Funktion ein einzelnes Ergebnis oder NULL zurück.

Dasselbe kann für ein Lied getan werden, indem man einige Namen ändert.

this helps :)

+0

Danke für Ihre harte Arbeit, diese Lösung funktioniert auch, aber Die Ergebnisliste wird wie "Nachrichten" sein: NULL, "Lied": {}, nicht so elegant wie das polymophische. – xcaptain