Home > Blockchain >  get a list of users who I have contacted or they have contacted me
get a list of users who I have contacted or they have contacted me

Time:01-12

I'm working on messaging application (internal) and I would like to get a list of users who have contacted or I have contacted, just like facebook inbox ( on the left you see a list of users who contacted you or you have contacted )

I tried a lot but I couldn't success, what kind of relations I should use to get what I'm looking for, This is my migration

Schema::create('messages', function (Blueprint $table) {
            $table->increments('id');

            $table->unsignedBigInteger('sender_id');
            $table->unsignedBigInteger('receiver_id');

            $table->foreign('sender_id')->references('id')->on('users');
            $table->foreign('receiver_id')->references('id')->on('users');

            $table->text('message')->nullable();
            $table->timestamps();
        });

CodePudding user response:

One thing you could try is to use relationships in your User model.

public function sent_messages() {
        return $this->hasMany('App\Message','sender_id','id');
}

public function received_messages() {
        return $this->hasMany('App\Message','receiver_id','id');
}

Then get the messages with $user->sent_messages and $user->received_messages

CodePudding user response:

Consider this raw SQL query:

SELECT DISTINCT sender_id user_id
FROM messages
WHERE receiver_id = ?

UNION

SELECT DISTINCT receiver_id
FROM messages
WHERE sender_id = ?

If you substitute your user ID into both ? then you'll get a list of all users with who you ever communicated. Then you can easily form a list of chats or whatever you need.

UPD

Of course this solution isn't optimal. And it's fine only for low-loaded projects. If you need a really fast solution then you'll have to create a special caching table like chats (user1_id, user2_id) where you'll store unique pairs of (receiver_id, sender_id) and (sender_id, receiver_id) from messages. Then getting the list of chats will be as easy as SELECT user2_id FROM chats WHERE user1_id = ?

CodePudding user response:

This could be resolved in your blade view file once you've received the complete dataset.

In reference to the dataset received from your previously answered question:

I'm getting messages twice, duplicated

In your blade view file...

@foreach($chats as $chat)

@php($user = ($chat->from->id != \Auth::id()) ? $chat->from : $chat->to)

<span>{{$user->name}} - </span> <span>{{$chat->message}}</span>
<br />

@endforeach

Addendum

If in case you're only interested in the user list:

get a list of users who I have contacted or they have contacted me

In your Chat.php model, you could make use of a subquery...

// ...
    function contacts()
    {
        $authId = Auth::id();

        $contactIds = Chat::where('chats.from_id', $authId)->orWhere('chats.to_id', $authId)->select(["from_id", "to_id"])
            ->groupBy("from_id", "to_id")
            ->get()
            ->map(function ($user) use ($authId) {
                return ($user->from_id != $authId) ? $user->from_id : $user->to_id;
            })
            ->unique();

        return \App\Models\User::whereIntegerInRaw("id", $contactIds)
            ->get(["id", "name"]);
    }
// ...
  •  Tags:  
  • Related