获取“像聊天室”的聊天列表

时间:2019-08-23 18:10:30

标签: mysql laravel eloquent model

我的代码有问题。我想获得唯一的用户/会话。 我的数据库看起来像这样

ID| FROM | TO | MESSAGE 

我想获得此聊天的唯一列表,但是当我有(1,2)(2,1)的人回答时,我的记录翻了一番。

Message::select('from','to','message','created_at')->latest()->where('from',Auth::id())->orWhere('to',Auth::id())->with('from','to')->distinct('from','to')->get()

2 个答案:

答案 0 :(得分:0)

您实际上想要的是一个列表,该列表与您当前已通过身份验证的用户之前进行过对话。您可以通过以下查询获取此用户:

use Illuminate\Database\Eloquent\Builder;

$authId = auth()->id();

$users = User::query()
    ->whereHas('messages', function (Builder $query) use ($authId) {
        $query->where('from', $authId)
            ->orWhere('to', $authId);
    })
    ->get();

然后,您可能希望显示每个用户的对话预览,最有可能显示您所描述的最新消息。检索此消息可能很棘手,但是借助子查询和特殊关系,它非常简单。

首先,我们需要扩展用户查询,使其还包括最新消息的ID:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;

$authId = auth()->id();

$users = User::query()
    ->whereHas('messages', function (Builder $query) use ($authId) {
        $query->where('from', $authId)
            ->orWhere('to', $authId);
    })
    ->where('id', '!=', $authId)
    ->select()
    ->selectSub(function (QueryBuilder $query) use ($authId) {
        $query->from('messages')
            ->where(function (QueryBuilder $query) use ($authId) {
                $query->whereColumn('messages.from', 'users.id')
                    ->where('messages.to', $authId);
            })
            ->orWhere(function (QueryBuilder $query) use ($authId) {
                $query->whereColumn('messages.to', 'users.id')
                    ->where('messages.from', $authId);
            })
            ->orderByDesc('created_at')
            ->limit(1)
            ->select('id');
    }, 'last_message_id')
    ->get();

然后,我们只需为用户模型上的最新消息定义一个HasOne关系:

use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Authenticatable
{
    public function lastMessage(): HasOne
    {
        return $this->hasOne(Message::class, 'id', 'last_message_id');
    }
}

现在,我们要做的就是向我们的查询中添加->with('lastMessage'),我们将使用来自当前身份验证用户或来自当前身份验证用户的最后一条消息来迭代用户。

答案 1 :(得分:0)

在这一刻,我想出了这样的想法。而这项工作。如果有人有更好的解决方案。

webviewPlugin. hide() ;

User.php

 $authId = auth()->id();

    $users =
        User::query()->whereHas('messages_from', function (Builder $query) use ($authId) {
            $query->where('from', $authId)
                ->orWhere('to', $authId);
        })->where('id', '!=', $authId)
        ->orwhereHas('messages_to', function (Builder $query) use ($authId) {
        $query->where('from', $authId)
            ->orWhere('to', $authId);
    })
        ->where('id', '!=', $authId)
        ->select()
        ->selectSub(function (QueryBuilder $query) use ($authId) {
            $query->from('messages')
                ->where(function (QueryBuilder $query) use ($authId) {
                    $query->whereColumn('messages.from', 'users.id')
                        ->where('messages.to', $authId);
                })
                ->orWhere(function (QueryBuilder $query) use ($authId) {
                    $query->whereColumn('messages.to', 'users.id')
                        ->where('messages.from', $authId);
                })
                ->orderByDesc('created_at')
                ->limit(1)
                ->select('message');
        }, 'message')
        ->get();
    return $users->jsonSerialize();