【问题标题】:Fetch users with their unread messages with Laravel Join vs Laravel Eloquent使用 Laravel Join 与 Laravel Eloquent 获取用户未读消息
【发布时间】:2020-03-20 13:40:05
【问题描述】:

我正在开发一个聊天应用程序。我正在获取所有用户以显示在侧边栏中。对于每个用户,我还想显示来自任何用户的未读消息的指示。我有这样的 messages 表。


id | user_id | receiver_id | 留言 | is_read


标准用户表的 Laravel。我通过控制器方法中的以下 join 实现了它。

public function users_join()
{
    // get logged in user
    $user = Auth::id();
    // left join to get all users all time
    return DB::table('users')->where('users.id', '!=', $user)
        ->leftJoin('messages', function ($join) use ($user) {
            // first evaluate where in below function
            $join->on('users.id', '=', 'messages.user_id')
                // filter messages sent to current user
                ->where('messages.receiver_id', '=', $user)
                // get only those messages which are unread
                ->where('messages.is_read', '=', 0);
        })->select('users.*', 'messages.user_id', 'messages.receiver_id', 'messages.message'
            , 'messages.is_read')
        // finally grouped by email to get only 10 records from users table
        ->orderBy('messages.created_at', 'DESC')->groupBy('email')->get();
}

现在我想用 Laravel Eloquent 来做。如果不使用循环,我想不出任何其他方式来做到这一点。这是它的代码。

public function users_eloquent()
{
    // get current user
    $current_user = Auth::id();
    // each through all users except current
    $users = User::all()->except($current_user)->each(function ($user) use ($current_user) {
        // laravel relationship
        $user->messages = $user->messages()
            // messages sent to me
            ->where('receiver_id', $current_user)
            // unread message sent to me
            ->where('is_read', 0)
            // get latest unread message
            ->orderBy('created_at', 'DESC')
            // first latest message
            ->first();
    });
    // send back the response
    return $users;
}

我的用户模型是这样的

public function messages()
{
    return $this->hasMany('App\Message');
}

以防万一,我的Message模型是这样的

public function user()
{
    return $this->belongsTo('App\User');
}

我想用 Eloquent 实现它而不使用每个循环。我该怎么做?

我在边栏中有所有用户及其未读标记。以下是所附截图。

谢谢!

【问题讨论】:

    标签: laravel


    【解决方案1】:

    您不需要循环所有用户。

    你可以在 Eloquent 模型上通过 where() 方法找到除 current_user 之外的用户,然后才能成为集合。

    并使用with() 为这些用户获取最新消息:

    $current_user = Auth::id();
    
    return User::where('id', '<>', $current_user)
                ->with(['messages' => function($q) use ($current_user) {
                          $q->where('receiver_id', $current_user)
                            ->where('is_read', 0)
                            ->latest()
                            ->first();
                }])->get();
    

    【讨论】:

    • 成功了。我不知道你可以用'with'来做'where'。我一直在寻找这种解决方案。你增加了我的知识。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 2010-09-09
    • 2014-11-17
    • 2020-06-06
    • 2016-09-28
    • 2017-02-09
    • 1970-01-01
    相关资源
    最近更新 更多