Получайте пользователей с их непрочитанными сообщениями с помощью Laravel Join против Laravel Eloquent - PullRequest
0 голосов
/ 20 марта 2020

Я работаю над приложением чата. Я загружаю всех пользователей, чтобы показать на боковой панели. С каждым выбранным пользователем я также хочу показать указание непрочитанных сообщений от любого пользователя. У меня есть таблица messages , как эта.


id | user_id | receive_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 . Я не могу придумать другой способ сделать это без использования l oop. Вот код для этого.

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');
}

и на всякий случай, мое Сообщение Модель такая:

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

Я хочу добиться этого с Eloquent без использования каждого l oop. Как я могу это сделать?

У меня есть все пользователи на боковой панели и их непрочитанная отметка. Ниже приведен скриншот.

Спасибо!

chat application picture

1 Ответ

1 голос
/ 20 марта 2020

Вам не нужно l oop всем пользователям.

Вы можете найти пользователя, кроме метода current_user с помощью where() на модели Eloquent, прежде чем она станет коллекцией.

И использовать 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...