如何在数据透视表 table 中搜索由两个用户拥有的行
How to search a pivot table for rows that are owned by two users
抱歉,如果这是一个愚蠢的问题,但我是 Laravel 的新手。
我有两个模型和一个枢轴 table:
用户
id | name | password
public function conversations(): ?BelongsToMany
{
return $this->belongsToMany(Conversation::class)->withTimestamps();
}
对话
id
public function users(): ?BelongsToMany
{
return $this->belongsToMany(User::class)->withTimestamps();
}
conversation_user
id | conversation_id | user_id
我创建了一个对话并像这样为用户分配同步:
$user->conversations()->syncWithoutDetaching($conversation);
$targetUser->conversations()->syncWithoutDetaching($conversation);
一个用户可以有多个会话,一个会话可以有多个用户。这很好,但是当我想与两个特定用户进行对话时,我不知道利用 ORM 查找他们各自所属的对话的最佳方式。
我目前正在使用下一个方法,它有效但感觉有更好的方法利用 ORM 做事:
/**
* Get a conversation by a target user id.
*
* @param int $targetUserId
* @return mixed
*/
public function getConversationByTargetUserId(int $targetUserId)
{
// Get the current user.
$user = Auth::guard()->user();
// Check the user exists.
if (!$user) {
throw new HttpException(500);
}
/**
* Get all pivot tables where the
* user ID is from the current user.
*/
$userConversationIdsArray = DB::table('conversation_user')->where('user_id', $user->id)->pluck('conversation_id');
/**
* Get all pivot tables where the user
* id is equal to the target id, and is
* also owned by the current user. Return
* the first instance that we come across.
*/
$targetConversation = DB::table('conversation_user')->where(['conversation_id' => $userConversationIdsArray, 'user_id' => $targetUserId])->first();
/**
* Return the conversation.
*/
return Conversation::find($targetConversation->conversation_id);
}
感谢您的宝贵时间:)
您没有使用 Eloquent 有什么特别的原因吗?它可能会更容易。
可以这样做,因为您已经有了用户。
$user->conversations()->has('users.id', '=', $targetUserId)->first();
(我没有测试过这个解决方案,所以我不确定它是否 100% 有效)
此外,您的第一个查询中可能有错字。可能是复制粘贴错误可能是打字错误。只是确定一下。
$userConversationIdsArray = DB::table('conversation_user')->where('user_id', $user->id)->pluck('id'); <---- 'id' shouldn't that be 'conversation_id'?
感谢@Fjarlaegur,他们让我走上了正轨。以下方法有效:
/**
* Get a conversation by a target user id.
*
* @param int $targetUserId
* @return mixed
*/
public function getConversationByTargetUserId(int $targetUserId)
{
// Get the current user.
$user = Auth::guard()->user();
// Check the user exists.
if (!$user) {
throw new HttpException(500);
}
return $user->conversations()->whereHas('users', function ($query) use ($targetUserId) {
$query->where('users.id', $targetUserId);
})->first();
}
抱歉,如果这是一个愚蠢的问题,但我是 Laravel 的新手。
我有两个模型和一个枢轴 table:
用户
id | name | password
public function conversations(): ?BelongsToMany
{
return $this->belongsToMany(Conversation::class)->withTimestamps();
}
对话
id
public function users(): ?BelongsToMany
{
return $this->belongsToMany(User::class)->withTimestamps();
}
conversation_user
id | conversation_id | user_id
我创建了一个对话并像这样为用户分配同步:
$user->conversations()->syncWithoutDetaching($conversation);
$targetUser->conversations()->syncWithoutDetaching($conversation);
一个用户可以有多个会话,一个会话可以有多个用户。这很好,但是当我想与两个特定用户进行对话时,我不知道利用 ORM 查找他们各自所属的对话的最佳方式。
我目前正在使用下一个方法,它有效但感觉有更好的方法利用 ORM 做事:
/**
* Get a conversation by a target user id.
*
* @param int $targetUserId
* @return mixed
*/
public function getConversationByTargetUserId(int $targetUserId)
{
// Get the current user.
$user = Auth::guard()->user();
// Check the user exists.
if (!$user) {
throw new HttpException(500);
}
/**
* Get all pivot tables where the
* user ID is from the current user.
*/
$userConversationIdsArray = DB::table('conversation_user')->where('user_id', $user->id)->pluck('conversation_id');
/**
* Get all pivot tables where the user
* id is equal to the target id, and is
* also owned by the current user. Return
* the first instance that we come across.
*/
$targetConversation = DB::table('conversation_user')->where(['conversation_id' => $userConversationIdsArray, 'user_id' => $targetUserId])->first();
/**
* Return the conversation.
*/
return Conversation::find($targetConversation->conversation_id);
}
感谢您的宝贵时间:)
您没有使用 Eloquent 有什么特别的原因吗?它可能会更容易。
可以这样做,因为您已经有了用户。
$user->conversations()->has('users.id', '=', $targetUserId)->first();
(我没有测试过这个解决方案,所以我不确定它是否 100% 有效)
此外,您的第一个查询中可能有错字。可能是复制粘贴错误可能是打字错误。只是确定一下。
$userConversationIdsArray = DB::table('conversation_user')->where('user_id', $user->id)->pluck('id'); <---- 'id' shouldn't that be 'conversation_id'?
感谢@Fjarlaegur,他们让我走上了正轨。以下方法有效:
/**
* Get a conversation by a target user id.
*
* @param int $targetUserId
* @return mixed
*/
public function getConversationByTargetUserId(int $targetUserId)
{
// Get the current user.
$user = Auth::guard()->user();
// Check the user exists.
if (!$user) {
throw new HttpException(500);
}
return $user->conversations()->whereHas('users', function ($query) use ($targetUserId) {
$query->where('users.id', $targetUserId);
})->first();
}