如何从具有一对一和多对关系的 3 个模型中获取数据?
How to get data from 3 models connected with Has-One and Have-Many relationship?
我的项目中有一个交友请求模块。其中使用了以下 3 个表格:-
- 用户
- User_profile
- 友谊
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());
}
我的项目中有一个交友请求模块。其中使用了以下 3 个表格:-
- 用户
- User_profile
- 友谊
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());
}