2013-07-25 9 views
8

Qual è il modo migliore per modellare un rapporto di amicizia con eloquente? Il mio schema di tabella è sotto e vorrei definire una relazione in cui potrei recuperare tutti gli amici qualcosa come segue.Laravel ORM Amicizia Relazione senza duplicazione

<?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 | 
+----+---------+-----------+----------+---------------------+---------------------+ 

Il rapporto di cui sopra è vicino a lavorare quando mi cerca amici con l'id utente di 3 ottengo utenti 1 e 3, ma ovviamente voglio 1 e 2.

Amicizia Tabella

user_id: l'ID utente che ha richiesto l'amicizia
friend_id: l'ID utente dell'amico selezionato
stato: se l'amicizia è in sospeso, accettata o bloccata.
created_at e updated_at

Sono consapevole del fatto che ci sono soluzioni da Laravel Many to many self referencing table only works one way dove posso recuperare gli amici da entrambi i lati della relazione, ma devo essere due file, ad esempio, se l'utente 1 e 3 sono gli amici, poi in uno riga user_id = 3 e friend_id = 1, e nella riga successiva vice versa. (O se non ho due righe devo fare due domande).

risposta

3

Non si dovrebbe cercare di trasformare quello che dovrebbe essere di due righe in una riga, ma se avete intenzione di provare a farlo allora sicuramente non si hanno bisogno di colpire il database per due volte:

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

che in laravel sarebbe:

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

Si potrebbe anche fare sub-wheres al gruppo t orlo, ma questo è un po 'complicato.

5

È possibile eseguire due ricerche, and use a union query, raggiungendo quindi il database una sola volta. Mettete il tutto in una funzione personalizzata:

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

Grazie questo sembra esattamente quello che voglio comunque ho ricevuto questo errore L'argomento 1 passato a Illuminate \ Database \ Query \ Builder :: mergeBindings() deve essere un'istanza di Illuminate \ Database \ Query \ Builder, istanza di Illuminate \ Database \ Eloquent \ Relations \ BelongsToMany dato, chiamato in /var/www/cc/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php sulla riga 857 e definito –

-3

Ho un suggerimento di utilizzare le condizioni per caricare i vlaues desiderati

  • in questo esempio diciamo che si è utilizzato query per caricare user_id e fiend_id con condizioni,

    "select * from frienddship DOVE ID_utente = '$ id' O friend_ID = '$ id'"

$ id: è l'id utente che si desidera mostrare ai propri amici.

all'interno del ciclo while PHP che u utilizzare per caricare i risultati è possibile filtrare resulets facendo condizione

while ... { 

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

$f_id = friendship['friend_id'] ; } 

// other instructionS... 

else { 

$f_id = friendship['user_id'] ; } 

// other instructionS... 

} 

in questo caso si dovrà caricare dati da colonne della tabella bothe e quindi ogni volta filtrata colonna con l'id utente e lascia solo l'id del suo amico, il filtro non diceva all'utente che sei amico di te stesso.

dispiace ho usato mysql per spiegare l'esempio

+0

Non sono sicuro di come potrei usarlo Eloquente? –

Problemi correlati