如何从具有一对一和多对关系的 3 个模型中获取数据?

How to get data from 3 models connected with Has-One and Have-Many relationship?

我的项目中有一个交友请求模块。其中使用了以下 3 个表格:-

  1. 用户
  2. User_profile
  3. 友谊

Users :- Id,slug,Name,Email, Password

UserProfile :- Id, user_slug, Profile_pic, DOB..etc.

Friendship :- Id, User_slug, Friend_slug, Status

关系:-

用户模型:-

public function Profile(){
    return $this->hasOne('UserProfile','user_slug','slug')->first();
}

public function sentFriendshipRequests(){
    return $this->hasMany('Friendship','user_slug','slug');
}

public function receivedFriendshipRequests(){
    return $this->hasMany('Friendship','friend_slug','slug');
}   

用户档案模型:-

public function User(){
    return $this->belongsTo('User','user_slug','slug');
}

友情模型:-

public function receiver(){
    return $this->belongsTo('User','friend_slug','slug');
}


public function sender(){
    return $this->belongsTo('User','user_slug','slug');
}

目标:-我想显示用户收到的待定好友请求列表。

所需资料:- 当前登录用户和好友请求发送者的姓名,Slug,Profile_pic 的所有好友请求处于待处理状态。

我的做法:-

$friendship_requests= Auth::user()->receivedFriendshipRequests();

foreach($friendship_requests as $frnd_req)
{
    $sender_user=User::where('slug',$frnd_req->user_slug());
}

是否有任何其他正确的方法可以通过使用 Eloquent 关系方法而不使用连接来获取此数据。我的意思是如何在一个查询中使用 HasOne 和 HasMany 关系获取数据。

非常感谢任何帮助或建议。

谢谢

这是一个自引用的多对多关系,因此您根本不需要那些 hasMany/belongsTo 关系。 您可以简单地将一个 belongsToMany 用于自己的请求,另一个用于收到的请求。

先读一下:

然后添加这些关系:

// pending requests of mine
function pendingFriendsOfMine()
{
  return $this->belongsToMany('User', 'friendship', 'user_slug', 'friend_slug')
     ->wherePivot('accepted', '=', 0)
     ->withPivot('accepted');
}

// pending received requests
function pendingFriendOf()
{
  return $this->belongsToMany('User', 'friendship', 'friend_slug', 'user_slug')
     ->wherePivot('accepted', '=', 0)
     ->withPivot('accepted');
}

// accessor allowing you call $user->friends
public function getPendingFriendsAttribute()
{
    if ( ! array_key_exists('pendingFriends', $this->relations)) $this->loadPendingFriends();

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

protected function loadPendingFriends()
{
    if ( ! array_key_exists('pendingFriends', $this->relations))
    {
        $pending = $this->mergePendingFriends();

        $this->setRelation('pendingFriends', $pending);
    }
}

protected function mergePendingFriends()
{
    return $this->pendingFriendsOfMine->merge($this->pendingFriendOf);
}

然后你只需使用嵌套关系加载它:

$user = Auth::user();
$user->load('pendingFriendsOfMine.profile', 'pendingFriendOf.profile');
// the above will execute 4 queries - 2 for requests, 2 for related profiles

$pendingFriends = $user->pendingFriends; // for all pending requests
// or
// $user->load('pendingFriendOf.profile'); // 2 queries in this case
// $pendingRequests = $user()->pendingFriendOf; // for received requests only

foreach ($pendingFriends as $user) {
  $user->profile; // eager loaded profie model
}

此外,您的代码中存在一些错误:

// there can't be first() in the relation definition
// and it is not needed anyway
public function Profile(){
    return $this->hasOne('UserProfile','user_slug','slug')->first();
}



// You never want to run this User::where() ...
// in a foreach loop, for it will result in n+1 queries issue
// You need eager loading instead.
foreach($friendship_requests as $frnd_req)
{
    $sender_user=User::where('slug',$frnd_req->user_slug());
}