与Laravel的友谊制度:多对多关系 [英] Friendship system with Laravel : Many to Many relationship

查看:80
本文介绍了与Laravel的友谊制度:多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用Laravel创建一个友谊系统(我从它开始),但是我被关系阻止了。这里的东西:有一个表用户和一个表的朋友包含以下列:

 朋友:id,user_id,friend_id ,接受。 

它看起来像一个很多到许多,所以这里是我设置的用户类:

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

但是当我尝试一下:

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

我有这个错误:

 基数表或视图未找到:1146表'base.user_user'不存在

我想获取用户的朋友的列表,如果用户发送邀请或收到用户的话,则无关紧要。所以用户可以使用user_id或者friend_id,然后根据该列检索其他用户的数据。



任何想法?谢谢!



编辑:这是我使用的代码:

  $ usersWithFriends = User :: with('friendsOfMine','friendOf') - > get(); 
$ user = User :: find(Auth :: id()) - > friends;

foreach($ user as $ item){
echo $ item-> first() - > pivot-> accepted;
}


解决方案

tldr;您需要2个倒置关系才能使其正常运行,请检查SETUP和USAGE以下






首先关闭错误 - 这是你的关系应该如下所示:

  function friends()
{
return $ this-> belongsToMany('User','friends','user_id','friend_id')
//如果要依赖接受字段,则添加:
- > wherePivot ('accepted','=',1);
}

然后它会工作没有错误:

  $ user-> friends; //收集用户模型,返回相同:
$ user-> friends() - > get();






SETUP



然而,您希望关系能够以两种方式工作。雄辩不提供这种关系,所以你可以使用2个倒置关系并合并结果

  //我开始的朋友
function friendsOfMine()
{
return $ this-> belongsToMany('User','friends','user_id','friend_id ')
- > wherePivot('accepted','=',1)//仅过滤接受的
- > withPivot('accepted'); //或获取接受的值
}

//我被邀请到
的朋友friendOf()
{
return $ this-> ; belongsToMany('User','friends','friend_id','user_id')
- > wherePivot('accepted','=',1)
- > withPivot('accepted' );
}

//访问器允许您调用$ user-> friends
public function getFriendsAttribute()
{
if(!array_key_exists('friends ',$ this->关系))$ this-> loadFriends();

return $ this-> getRelation('friends');
}

protected function loadFriends()
{
if(!array_key_exists('friends',$ this->关系))
{
$ friends = $ this-> mergeFriends();

$ this-> setRelation('friends',$ friends);
}
}

保护函数mergeFriends()
{
返回$ this-> friendsOfMine-> merge($ this-> friendOf );
}



USAGE



通过这样的设置,您可以执行以下操作:

  //访问所有的朋友
$ user-> //收集唯一的用户模型实例

//访问朋友一个用户邀请
$ user-> friendsOfMine; // collection

//访问由用户受邀的朋友
$ user-> friendOf; //收集

//和eager加载所有有2个查询的朋友
$ usersWithFriends = User :: with('friendsOfMine','friendOf') - > get();

// then
$ users-> first() - > friends; // collection

//检查接受的值:
$ user-> friends-> first() - > pivot-> accepted;


I'm trying to create a Friendship system with Laravel (I'm starting with it) but I'm blocked with relationships. Here's the thing : there is one table Users and one table Friends which contains the following columns :

friends: id, user_id, friend_id, accepted.

It looks like a Many to Many so here's what I set on User class :

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

But when I try a :

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

I have this error :

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

I would like to get a list of the Friends of a user, no matters if the user sent the invitation or received it. So the user can ba on user_id or on friend_id and then I retrieve the data of the other user depending of that column.

Any idea? Thank's!

EDIT : Here's the code I use :

$usersWithFriends = User::with('friendsOfMine', 'friendOf')->get();
$user = User::find(Auth::id())->friends;

foreach($user as $item) {
    echo $item->first()->pivot->accepted;
} 

解决方案

tldr; you need 2 inverted relationships to make it work, check SETUP and USAGE below


First off the error - this is how your relation should look like:

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);
}

Then it will work without errors:

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


SETUP

However you would like the relation to work in both ways. Eloquent doesn't provide a relation of that kind, so you can instead use 2 inverted relationships and merge the results:

// 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 ( ! array_key_exists('friends', $this->relations)) $this->loadFriends();

    return $this->getRelation('friends');
}

protected function loadFriends()
{
    if ( ! array_key_exists('friends', $this->relations))
    {
        $friends = $this->mergeFriends();

        $this->setRelation('friends', $friends);
    }
}

protected function mergeFriends()
{
    return $this->friendsOfMine->merge($this->friendOf);
}

USAGE

With such setup you can do this:

// 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;

这篇关于与Laravel的友谊制度:多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆