Consider adding a hasConversationWith($user) method to your User model.
Check if conversation between 2 users exist
Hello,
i'm trying to achieve a private messaging system in Laravel but i'm stuck by checking if a conversation exist.
I have 3 Tables:
conversations
- id
users
- id
- name
- etc
conversation_user (pivot)
- user_id
- conversation id
My model Conversation belongsToMany Users and User belongsToMany Conversations.
Adding a conversation and attaching the users to the pivot table is working fine but i don't find a clean way to check if a conversation between 2 users exist.
I appreciate any help.
Ben
But what if a User has a conversation with many users? Something like a group conversation.
You should be able to implement that function so it accepts an array of users or user IDs. The function would probably need to work directly on the pivot table.
To be honest, I've no idea how your system works. I'm not sure I understand the need for such a function. Would you not simply display a list of conversations for a given user?
Can you give me a use case for the feature you are describing?
Sorry. If a user clicks on 'send message to user' or something like that, i need to check if this conversation allready exist. If so i will load the previous messages, if not i want to create a new conversation between these two users.
And what if there is more than one conversation? How do you get the right one?
I'm really struggling trying to visualise how this is going to work.
There will be always just one conversation between user 1 and user 2. thats my goal.
You mentioned the concept of a "group conversation". What would happen when user 3 gets invited into the conversation, if user 3 already has an existing conversation with user 1 but not user 2? What conversations would you expect to find in the database? Who can invite new users to join a conversation?
I'm not entirely sure that your table structure suits your needs, but it really depends on exactly what you're hoping to achieve.
Ok let's kill this idea of a conversation between more then 2 users. It's a learning project for me so i will start with basic conversations.
I have a few test conversations an when i query them, i get all conversations including the users and the pivot table, but i can't imagine how to check if one of the conversations is for example between user_id 1 and user_id 2.
$conversations = Conversation::with('users')->get();
Ok i got a solution, is this a good way?
// Get all conversations with users
$conversations = Conversation::with('users')->get();
$user_ids = [1, 1]; // For testing purposes
// Loop through all conversations
foreach ($conversations as $conversation)
{
$users = $conversation->users;
$existingUsers = array();
foreach ($users as $user)
{
$existingUsers[] = $user->id;
}
$arraysAreEqual = ($existingUsers == $user_ids);
if ($arraysAreEqual == true){
return $conversation->id;
}
}
return 'No Conversation found';
I'm not sure if this solution will work as you expect. If the order of the arrays varies in anyway, your comparison will fail.
hi,
i was figuring out how to query it with mysql:
SELECT CU.conversation_id
FROM conversation_user CU
WHERE CU.user_id = 1
AND EXISTS (SELECT NULL FROM conversation_user CUO WHERE CUO.user_id = 2 AND CUO.conversation_id = CU.conversation_id);
is this also possible with the query builder?
This is what I used in one of my old projects. I also used conversations and when I wanted to send new message this is how I checked if user is in conversation or not:
public function store()
{
$rules = ["message" => "required", "user" => "required|integer"];
$validator = Validator::make(Input::all(), $rules);
$user = User::find(Input::get("user"));
if($validator->passes()){
$conv1 = Auth::user()->conversations->lists("id");
$conv2 = $user->conversations->lists("id");
// if there is conversation between logged in user and passed in user, then take it
if(count(array_intersect($conv1, $conv2)) > 0){
$conversation = Conversation::find(array_intersect($conv1, $conv2)[0]);
}else{
// otherwise make new conversation, the rest is easy to understand
$conversation = new Conversation;
$conversation->save();
$conversation->users()->attach([Auth::user()->id, $user->id]);
}
$message = new Message;
$message->user_id = Auth::user()->id;
$message->message = Input::get("message");
$message->conversation_id = $conversation->id;
$message->save();
return Redirect::to(URL::action("ConversationsController@show", $conversation->id));
}else{
return Redirect::back()->withInput()->withErrors($validator);
}
}
thank @alenn but i need this query, it's perfect and fast.
Please or to participate in this conversation.