2013-07-25 13 views
8

Was ist der beste Weg, um eine Freundschaft Beziehung mit eloquent zu modellieren? Mein Tabellenschema ist unten und ich möchte eine Beziehung definieren, in der ich alle Freunde wie folgt abrufen könnte.Laravel ORM Freundschaft Beziehung ohne Duplizierung

<?php 

class User extends Eloquent { 

public function friends() { 
    return $this->belongsToMany('User', 'friendships', 'user_id', 'friend_id')->orWhere($this->id,'=', 'friend_id'); 
    } 
} 

+----+---------+-----------+----------+---------------------+---------------------+ 
| id | user_id | friend_id | state | created_at   | updated_at   | 
+----+---------+-----------+----------+---------------------+---------------------+ 
| 1 |  3 |   1 | accepted | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | 
| 2 |  2 |   3 | accepted | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | 
+----+---------+-----------+----------+---------------------+---------------------+ 

Die Beziehung oben ist in der Nähe arbeiten, als ich für Freunde mit der Benutzer-ID von 3 sehe erhalte ich Benutzer 1 und 3, aber offensichtlich will ich 1 und 2

Freundschaft Tabelle

user_id: Die Benutzer-ID, die die Freundschaft angefordert hat friend_id: Die Benutzer-ID des Ziel-Freundes
Status: Ob die Freundschaft aussteht, akzeptiert oder blockiert ist.
created_at und updated_at

Ich bin mir bewusst, dass es Lösungen von Laravel Many to many self referencing table only works one way, wo ich die Freunde von beiden Seiten der Beziehung abrufen kann, aber ich muß zwei Reihen, zum Beispiel, wenn Benutzer 1 und 3 Freunde sind, dann in einer row user_id = 3 und friend_id = 1 und in der nächsten Reihe umgekehrt. (Oder wenn ich nicht zwei Zeilen habe, muss ich zwei Abfragen durchführen).

Antwort

3

Sie nicht versuchen sollten, und drehen, was zwei Zeilen in einer Reihe sein sollte, aber wenn Sie versuchen werden und das zu tun, dann auf jeden Fall nicht müssen die Datenbank zweimal getroffen:

select * from users where (user_id = :user_id and friend_id = :friend_id) or (friend_id = :friend_id and user_id = :user_id) 

das in Laravel wäre:

Users::whereRaw('(user_id = ? and friend_id = ?) or (friend_id = ? and user_id = ?)', [    
    $user_id, 
    $friend_id, 
    $friend_id, 
    $user_id 
]); 

Sie auch Unter wheres zu Gruppe t tun könnte Saum, aber das ist ein wenig kompliziert.

5

Sie könnten zwei Lookups, and use a union query, also nur die Datenbank einmal zu treffen. Setzen Sie all dies in einer benutzerdefinierten Funktion:

class User extends Eloquent { 

    public function friends() 
    { 
    $first = $this->belongsToMany('User', 'friendships', 'user_id', 'friend_id'); 
    return $this->belongsToMany('User', 'friendships', 'friend_id', 'user_id')->union($first); 
    } 
} 
+0

Danke das sieht genau wie ich will aber ich habe diesen Fehler Argument 1 an Illuminate \ Database \ Query \ Builder :: mergeBindings() muss eine Instanz von Illuminate \ Database \ Query \ Builder, Instanz von Illuminate \ Database sein \ Eloquent \ Relations \ BelongsToMany gegeben, in /var/www/cc/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php auf Linie 857 und definiert –

-3

Ich habe einen Vorschlag, die Sie Bedingungen verwenden, um die vlaues Sie laden

  • in diesem Beispiel wollen wir sagen, dass Sie Abfrage verwendet laden user_id und fiend_id mit der Bedingung,

    "select * from frienddship WHERE benutzer_ID = '$ id' OR friend_ID = '$ id'"

$ id: ist die Benutzer-ID, die Sie seinen Freunden zeigen möchten.

innerhalb der while-Schleife in PHP, die u die Ergebnisse verwenden laden Sie können resulets filtern, indem Bedingung machen

while ... { 

if (friendship['user_id'] == $id) { 

$f_id = friendship['friend_id'] ; } 

// other instructionS... 

else { 

$f_id = friendship['user_id'] ; } 

// other instructionS... 

} 

in diesem Fall von Daten aus bothe Tabellenspalten geladen wird und dann filtern jeweils die Spalte mit der Benutzer-ID und lassen Sie nur die ID seines Freundes, der Filter verwendet, um dem Benutzer nicht zu sagen, dass Sie mit sich selbst befreundet sind.

leider verwendet i mysql das Beispiel zu erklären

+0

Ich bin mir nicht sicher, wie ich das verwenden könnte Beredt? –