У меня есть проект, где пользователь может создавать беседы с другими пользователями. Разговор может belongsToMany
пользователи и пользователь могут belongsToMany
разговоры.
Теперь мне нужно получить разговор, в котором участвуют два конкретных пользователя.
Я попробовал комбинацию решений, используя whereIn
и я попробовал следующее:
$c = Conversation::whereHas('users', function($q)
{
$q->whereIn('user_id', array(1,3));
})
->get();
Здесь проблема в том, что whereIn('user_id', [1,3])
получает записи, содержащие ИЛИ 1 или 3. Мне нужно, чтобы вернуть записи, которые содержат И ТО И ДРУГОЕ 1 и 3.
Модель разговора
class Conversation extends Model {
public function users(){
return $this->belongsToMany('App\User');
}
}
Модель пользователя
class User extends Model {
public function conversations(){
return $this->belongsToMany('App\Conversation');
}
}
таблицы
беседы:
id | предмет
conversation_user:
id | user_id | conversation_id
Данные из таблицы разговор_пользователя
Ваше новое редактирование имеет гораздо больше смысла, на самом деле это очень легко исправить. whereHas
принимает два дополнительных параметра, где он будет искать количество.
$users = [1, 3];
$c = Conversation::whereHas('users', function($q) use ($users)
{
$q->whereIn('user_id', $users);
}, '>', count($users) )
->get();
Это позволит получить все разговоры, в которых участвовали пользователи 1 и 3, даже если в этих беседах участвовали дополнительные пользователи. Если вы хотите общаться только с пользователями 1 и 3, измените >
для =
,
Изменить: я только что понял, что ваша сводная таблица имеет id
колонка. Этот метод может не работать, если в вашей сводной таблице будут дубликаты. Например, если у вас есть user_id, равный 1, дважды с одним и тем же dialog_id оба раза, он вернет этот диалог, даже если технически у него только 1 пользователь. Я предлагаю удалить id
столбец и создание составного первичного ключа user_id
а также conversation_id
, Если есть возможность дублирования, было бы безопаснее использовать решение lukasgeiter.
Вы в настоящее время запрашиваете разговоры, которые либо пользователь 1 и /или же 3 принимает участие. Для достижения того, что вы хотите, вам нужно два whereHas
звонки:
$c = Conversation::whereHas('users', function($q)
{
$q->where('user_id', 1);
})
->whereHas('users', function($q)
{
$q->where('user_id', 3);
}
->get();
И если у вас более двух пользователей, добавьте их в цикле:
$users = [1, 2, 3, 4, 5];
$c = Conversation::query();
foreach($users as $userId){
$c->whereHas('users', function($q) use ($userId)
{
$q->where('user_id', $userId);
});
}
$c = $c->get();
Я надеюсь, что это поможет вам…
$userIds = array(1,3);
$c = Conversation::whereHas('users', function($q) use ($userIds)
{
$q->whereIn('user_id', $userIds);
})
->get();