Sistema di amicizia con Laravel: relazione da molti a molti

Sto provando a creare un sistema di amicizia con Laravel (sto iniziando con esso) ma sono bloccato dalle relazioni. Ecco la cosa: c'è una tabella Utenti e una tabella Amici che contiene le seguenti colonne:

friends: id, user_id, friend_id, accepted. 

Assomiglia a molti a molti, ecco cosa ho impostato sulla class User:

 class User extends Eloquent { function friends() { return $this->belongsToMany('User'); } } 

Ma quando provo a:

 $friends = User::find($id)->friends()->get() 

Ho questo errore:

 Base table or view not found: 1146 Table 'base.user_user' doesn't exist 

Vorrei get un elenco degli Amici di un utente, non import se l'utente ha inviato l'invito o ricevuto. Quindi l'utente può usare user_id o su friend_id e poi recuperare i dati dell'altro utente a seconda di quella colonna.

Qualche idea? Grazie!

EDIT: Ecco il codice che uso:

 $usersWithFriends = User::with('friendsOfMine', 'friendOf')->get(); $user = User::find(Auth::id())->friends; foreach($user as $item) { echo $item->first()->pivot->accepted; } 

TLDR; hai bisogno di 2 relazioni invertite per farlo funzionare, controlla SETUP e USAGE qui sotto


Innanzitutto l' errore : ecco come dovrebbe apparire la tua relazione:

 function friends() { return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id') // if you want to rely on accepted field, then add this: ->wherePivot('accepted', '=', 1); } 

Quindi functionrà senza errori:

 $user->friends; // collection of User models, returns the same as: $user->friends()->get(); 

IMPOSTARE

Comunque vorresti che la relazione funzionasse in entrambi i modi. Eloquent non fornisce una relazione di quel tipo, quindi puoi usare 2 relazioni invertite e unire i risultati :

 // friendship that I started function friendsOfMine() { return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id') ->wherePivot('accepted', '=', 1) // to filter only accepted ->withPivot('accepted'); // or to fetch accepted value } // friendship that I was invited to function friendOf() { return $this->belongsToMany('User', 'friends', 'friend_id', 'user_id') ->wherePivot('accepted', '=', 1) ->withPivot('accepted'); } // accessor allowing you call $user->friends public function getFriendsAttribute() { if ( ! arrays_key_exists('friends', $this->relations)) $this->loadFriends(); return $this->getRelation('friends'); } protected function loadFriends() { if ( ! arrays_key_exists('friends', $this->relations)) { $friends = $this->mergeFriends(); $this->setRelation('friends', $friends); } } protected function mergeFriends() { return $this->friendsOfMine->merge($this->friendOf); } 

USO

Con questa configuration puoi fare questo:

 // access all friends $user->friends; // collection of unique User model instances // access friends a user invited $user->friendsOfMine; // collection // access friends that a user was invited by $user->friendOf; // collection // and eager load all friends with 2 queries $usersWithFriends = User::with('friendsOfMine', 'friendOf')->get(); // then $users->first()->friends; // collection // Check the accepted value: $user->friends->first()->pivot->accepted; 

È davvero un problema nel tuo DB e anche nella definizione della relazione. Il tipo di relazione molti-a-molti si aspetta che tu usi e la tabella intermedia. Ecco cosa devi fare:

  1. Crea una user_friend (id, user_id, fried_id) nello schema.
  2. Rimuovi i campi non necessari dalle tabelle degli user e degli friend .
  3. Crea le chiavi esterne appropriate. user.id -> user_friend.user_id , friend.id -> user_friend.friend_id
  4. Meglio definire la relazione completa sui templates User e Friend ,

per esempio :

  class User extends Eloquent { function friends() { return $this->belongsToMany('User', 'user_friend', 'user_id', 'friend_id'); } } 

Puoi leggere molto di più in Laravel docs, QUI