2017-05-10 2 views
2
teil

Ich habe vier Tabellen. User, Conversations, Message and Conversation_Participants. I hope you don't find a relationship error in this image (ich hoffe, Sie keine Beziehung Fehler in diesem Bild finden)Laravel bekomme alle Konversationen mit Teilnehmern derzeitiger Benutzer nimmt an

Ich habe versucht, eine Funktion

public function conversations(){ 

    return $this->belongsToMany(Conversation::class, 'conversation_participants', 'user_id', 'conversation_id'); 
} 

zu User::class hinzufügen, aber wenn ich User::with('conversations')->get() nenne ich nur alle bestehenden Nutzer erhalten. Was mache ich falsch? Zuerst möchte ich alle Konversationen bekommen, an denen der aktuelle Benutzer teilnimmt und zweitens möchte ich alle Empfänger der Konversationen bekommen.

Ich habe auch versucht

public function participants() 
{ 
    return $this->belongsToMany(User::class, 'conversation_participants', 'user_id', 'conversation_id'); 
} 

im Conversation::class aber Conversation::with('participants')->get() bekommt mir alle Conversation auch diejenigen der Benutzer nicht in partizipiert

Ich bin wirklich verwirrt atm./

+0

Bitte versuchen Sie, Ihre 'partiancipants()' 'return $ this-> objectsToMany (App \ Benutzer, 'conversation_participants', 'conversation_id', 'user_id');' zu ändern. Und versuchen Sie in Ihrem Controller 'User :: mit ('Teilnehmer') -> get();' –

Antwort

2

Fügen Sie die folgenden in Ihrem User Modell:

public function conversations() { 
    return $this->belongsToMany(Conversation::class, 'conversation_participants', 'users_id', 'conversations_id'); 
} 

Und das zu Ihrem Conversation Modell:

public function participants() { 
    return $this->belongsToMany(User::class, 'conversation_participants', 'conversation_id', 'users_id'); 
} 

Wenn Sie Ihre Tabellen einfacher zu verknüpfen, read up on conventions.

alle Gespräche Um ein Benutzer beteiligt ist, führen Sie die folgende (vorausgesetzt, Sie den Benutzer geladen haben). $user->conversations() die Gespräche alle ein Benutzer zu bekommen

Wenn Sie alle Benutzer wollen, mit Alle ihre Gespräche, mit allen verbundenen Teilnehmern, tun folgendes: $users = Users::with('conversations.participants')->get(). Sie können nun eine Schleife durch das wie folgt aus:

foreach($users as $user) { 
    foreach($user->conversations as $conversation) { 
     foreach($conversations->participants as $participant) { 
      // do fancy stuff here 
     } 
    } 
} 

Beachten Sie, dass der Benutzer, von dem Sie starten, ist auch ein Teilnehmer, so müssen Sie vielleicht noch einmal, dass man auszufiltern.

Wenn Sie noch schicker werden möchten (aber mehr Ressourcen verwenden), können Sie sogar alle Nachrichten abfragen, die eine Konversation auch hat!

User::with('conversations.participants', 'conversations.messages.user')->get() 

Das funktioniert aber nur, wenn Sie einen zweiten Satz von Beziehungen entlang der oberen Tabelle in Ihrem Bild (conversations <-> messages <-> users)

bearbeiten

In den Kommentaren einrichten, fragte OP, wenn es möglich war, begrenzen Sie die Menge der Nachrichten aus der Datenbank abgerufen, die nach meinem Wissen möglich ist, aber ich jetzt nicht, wenn dies der beste Weg ist:

Entfernen Sie die Nachrichten von der ersten eage r Ladeteil:

User::with('conversations.participants') 

Danach, wenn Schleife durch die Gespräche, faul Last der Nachrichten:

$conversation->load(['messages' => function($query){ 
    $query->take(5); 
}, 'users']); 

Zugang sie danach mit $ Gesprächs-> Nachrichten.

Hinweis

Ich denke, das leichter in einem Rutsch erledigt werden könnte, aber ich habe kein Setup haben jetzt das für Sie zu testen.

Edit 2

Nach Ronon weiteren Kommentar hinzugefügt, hier ist, was ich kam mit:

Hinzufügen einer neuen Beziehung im Conversation Modell:

public function last_messages() { 
    return $this->hasMany(Message::class, 'conversation_id', 'id')->latest()->limit(2); 
} 

davon Da, Sie können jetzt folgendes tun:

User::with('conversations.participants', 'conversations.last_messages.users')->get() 

Wenn Sie weiterhin alle Nachrichten möchten, können Sie die messages-Beziehung verwenden. Wenn Sie weniger wollen, verwenden Sie die last_messages.

+0

Wow, danke. Der Teil mit den Nachrichten wäre in einem der nächsten Schritte gefolgt. Aber gibt es eine Möglichkeit, die geladenen Nachrichten zu begrenzen? Zum Beispiel nur die letzten 5 Nachrichten laden? Nachrichten haben auch die '$ table-> timestamps()' attr, also ist die Reihenfolge kein Problem. – Ronon

+0

Ja, lass mich meine Antwort bearbeiten! –

+0

@Ronon Es ist jetzt da –

1

Berufung User::with('conversations')->get() gibt keinen Benutzer an. Ich könnte Verlesen aber ich denke, Sie suchen nach etwas, wie die folgenden:

$user = User::with('conversations')->find(1); 
$userConversations = $user->conversations; 

, die Sie mit einem Benutzer und ihre Gespräche zur Verfügung stellt.

+0

Die Klammern in der letzten Zeile werden nicht benötigt, das würde Sie nur zurück in den Abfragemodus bringen. Für den Rest, genau richtig! –

+0

Danke, guter Fang! –

Verwandte Themen