Как найти несколько значений в базе данных и вернуть общий идентификатор (от многих к многим) - PullRequest
0 голосов
/ 14 апреля 2020

Я разрабатываю приложение для приватного чата, в котором настроены таблицы, как показано на рисунке ниже.

Tables

Для поддержки группового чата я сделал так, чтобы между беседами и пользователями существовала связь «многие ко многим» (разговор_пользователь). Это позволяет мне связывать / добавлять пользователей к беседам, не ограничивая его только двумя пользователями на беседу (sender_id, receient_id и c).

Для создания беседы ДОЛЖНЫ быть отправитель и получатель. , После инициализации беседы с этими двумя пользователями к беседе можно добавить больше пользователей.

Мой вопрос

Как проверить, существует ли существующая беседа который включает в себя отправителя и получателя.

То, что я пробовал

Это явно неправильный способ go, потому что это не дает мне желаемых результатов, но я пытаюсь найти любой экземпляр, в котором идентификаторы отправителя и получателя, которых я передаю, используют один и тот же идентификатор разговора. ПРИМЕЧАНИЕ: моя таблица 'разговор_пользователя' названа 'участниками' в модели разговора. Я также предпочел бы получать соответствующие подробности из разговора, а не пользователей, которые я уже знаю, как это сделать.

$existingConversation = Conversation::whereHas('participants')->with(['participants' => function($query) use ($request) {
            $query->where('user_id', $request->recipient_id);
        }])
        ->whereHas('participants')->with(['participants' => function($query) use ($request) {
            $query->where('user_id', $request->sender_id);
        }])->groupBy('id')->get();

Пример сценария

У меня есть приведенные ниже записи в моей таблице базы данных. Database Table Rows

Бэкэнд получает sender_id: 1 и recipient_id: 3 от внешнего интерфейса. Запрос выполняется для поиска ЛЮБЫХ разговоров, в которых участвуют отправитель и получатель. В этом случае он должен вернуть присоединяющийся диалог 33.

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

Это не намного элегантнее, но я думаю, что это поможет вам иметь несколько идентификаторов.

// assuming $request->participant_ids will be your array of ids

$existingConversation = Conversation::with('participants');

foreach($request->participant_ids as $participant_id){
    $existingConversation->whereHas('participants', function($query) use ($participant_id){
        $query->where('user_id', $participant_id);
    });
}

$existingConversation = $existingConversation->get();

Редактировать:

Если то, что вы имеете в виду под элегантностью, это только с точки зрения синтаксиса я также предложил бы попытаться использовать локальную область действия

// in Conversation model
public function scopeHasParticipants($query, Array $participantArr){
    foreach($participantArr as $participant_id){
        $query->whereHas('participants', function($query) use ($participant_id){
            $query->where('user_id', $participant_id);
        });
    }

    return $query;
}

Тогда вы можете использовать это так:

// still assuming $request->participant_ids will be your array of ids
$existingConversation = Conversation::with('participants')->hasParticipants($request->participant_ids)->get();
0 голосов
/ 14 апреля 2020

Мне удалось придумать не элегантный способ, поэтому я все еще рад видеть, что придумывает кто-то еще. Я в основном выполняю один запрос, чтобы найти все разговоры с sender_id, а затем выполняю отдельный запрос к этим данным, чтобы найти все экземпляры, где найден receient_id. Мне кажется, что хаки sh ... но это работает, я думаю. Это определенно станет проблемой, если я захочу найти существующие разговоры, содержащие более двух пользователей.

$existingConversation = Conversation::with('participants')->whereHas('participants', function($query) use ($request){
    $query->where('user_id', $request->sender_id);
});

$existingConversation = $existingConversation->with('participants')->whereHas('participants', function($query) use ($request){
    $query->where('user_id', $request->recipient_id);
})->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...