Организация структуры чатов на laravel?

Ссылка скопирована
1 ответ

Столкнулся с довольно неочевидной для меня проблемой, когда решил сделать небольшой чат. На этапе проектирования БД столкнулся с очевидной проблемой "отношений друзей". Т.е. у меня есть 2 пользователя (оба из таблицы users), на основе их отношения есть М-М таблица chats, где есть 2 соответствующих поля: first_u_id и second_u_id. При выборке из Eloquent, очевидно, сталкиваюсь с проблемой, что приходится мёрджить отношения, что-то вроде этого:

/**      * Getter for combining all user chats      *      * @return Collection      */     public function getChatsAttribute() : Collection {          return $this->my_chats->merge($this->add_chats);              }      /**      * Chats, initiated by current user instance      *      * @return BelongsToMany      */     public function my_chats() : BelongsToMany     {         return $this->belongsToMany(User::class, 'users_chats', 'first_user_id', 'second_user_id', 'id', 'id')->using(UsersChats::class)->as('chats');     }      /**      * Chats where the user was invited      *      * @return BelongsToMany      */     public function add_chats() : BelongsToMany     {         return $this->belongsToMany(User::class, 'users_chats', 'second_user_id', 'first_user_id', 'id', 'id')->using(UsersChats::class)->as('chats');     }

/** * Getter for combining all user chats * * @return Collection */ public function getChatsAttribute() : Collection { return $this->my_chats->merge($this->add_chats); } /** * Chats, initiated by current user instance * * @return BelongsToMany */ public function my_chats() : BelongsToMany { return $this->belongsToMany(User::class, 'users_chats', 'first_user_id', 'second_user_id', 'id', 'id')->using(UsersChats::class)->as('chats'); } /** * Chats where the user was invited * * @return BelongsToMany */ public function add_chats() : BelongsToMany { return $this->belongsToMany(User::class, 'users_chats', 'second_user_id', 'first_user_id', 'id', 'id')->using(UsersChats::class)->as('chats'); }

Минус данного подхода очевиден - возврат коллекции, а не билдера, а значит все последующие надстройки не работают. В голову пришло решение что-то покрутить с представлениями, но, как будто это не самое оптимальное решение, да и в sql я не очень. Как вообще решают эту проблему? Хотелось бы оставить эту логику на уровне модели.

Дополнительно:

Зачем вам в members second_user_id и first_user_id может вместо 2 колонок, сделать 2 строки? И тогда не надо будет устраивать проблемы?

table chats  table members{     chat_id,     user_id }  function chats(){      retrun $this->belongsToMany(Chat::class, 'members'); }

table chats table members{ chat_id, user_id } function chats(){ retrun $this->belongsToMany(Chat::class, 'members'); }

Ну хотите выделить владельца чата ну добавьте в pivot таблицу is_owner (true, false). Или member_type - owner, member

Ответы:

Проблема в том что вы рассматриваете чат на двоих и только. Выносите всех пиров каждого диалога в отдельную таблицу и все будет хорошо

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

Для организации структуры чатов на Laravel можно использовать различные подходы и инструменты. Одним из самых популярных способов является использование пакета Laravel Echo в сочетании с Socket.io для реального времени обмена сообщениями.

Во-первых, установим необходимые пакеты. Для этого запустите команду:

composer require predis/predis
composer require pusher/pusher-php-server
npm install --save laravel-echo pusher-js

composer require predis/predis composer require pusher/pusher-php-server npm install --save laravel-echo pusher-js

Далее настроим Laravel Echo в файле bootstrap.js:

import Echo from "laravel-echo"
 
window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pushers-app-key',
    cluster: 'your-pushers-cluster',
    encrypted: true
});

import Echo from "laravel-echo" window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pushers-app-key', cluster: 'your-pushers-cluster', encrypted: true });

Затем настроим Pusher в файле .env:

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=your-app-cluster

BROADCAST_DRIVER=pusher PUSHER_APP_ID=your-app-id PUSHER_APP_KEY=your-app-key PUSHER_APP_SECRET=your-app-secret PUSHER_APP_CLUSTER=your-app-cluster

Создадим миграцию для таблицы сообщений:

php artisan make:migration create_messages_table

php artisan make:migration create_messages_table

В миграции опишем структуру таблицы:

Schema::create('messages', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('user_id');
    $table->text('message');
    $table->timestamps();
 
    $table->foreign('user_id')->references('id')->on('users');
});

Schema::create('messages', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->text('message'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); });

Выполним миграцию:

php artisan migrate

php artisan migrate

Создадим модель Message:

php artisan make:model Message

php artisan make:model Message

В модели опишем отношение с пользователем:

public function user()
{
    return $this->belongsTo(User::class);
}

public function user() { return $this->belongsTo(User::class); }

Теперь можем создать контроллер для работы с сообщениями и чатами, а также соответствующие представления.

Таким образом, используя Laravel Echo и Pusher, можно легко организовать структуру чатов на Laravel, обеспечивая реальное время обмена сообщениями между пользователями.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно