Live Demo - GitHub Repo

Часть 1 - Часть 2 - Часть 3 - Часть 4 - Часть 5 - Часть 6 - Часть 7

Пока что мы создали простое приложение, которое позволяет пользователям входить в систему и получать доступ к защищенной домашней странице. В этом разделе мы добавим на эту домашнюю страницу формы, которые позволят пользователю создать комнату или присоединиться к ней. Затем мы создадим несколько базовых представлений, похожих на Slack, с боковой панелью, в которой перечислены все комнаты, к которым присоединился пользователь, и представлением комнаты чата.

Нам нужно начать с создания новой модели комнаты, которую мы можем сохранить в нашей базе данных. Нам нужно иметь поля name и topic для каждой комнаты, чтобы мы могли начать с запуска генератора

mix phoenix.gen.json Room rooms name:string topic:string

Затем обновите сгенерированный файл миграции следующим образом

В нашем приложении мы хотим, чтобы пользователи могли сохранять список комнат. Для этого нам нужно будет создать объединенную таблицу с именем user_rooms. Прежде чем идти дальше, давайте создадим эту модель с помощью генератора Phoenix.

mix phoenix.gen.model UserRoom user_rooms user_id:references:users room_id:references:rooms

Последний индекс, index (: user_rooms, [: user_id,: room_id], unique: true), позволит нам создать unique_constraint с областью действия для пользователя и комнаты, что означает, что пользователь не сможет присоединиться к одной и той же комнате дважды. Вот реализация модели UserRoom.

А вот и наша новая модель комнаты.

Обратите внимание, что в модели Room мы определили отношения many_to_many с пользователями через таблицу user_room. Нам нужно добавить аналогичную строку в модель User - many_to_many: rooms, Sling.Room, join_through: «user_rooms».

Запустите миграции сейчас, если вы этого не сделали (закомментируйте room_controller, если он выдает ошибки)

mix ecto.migrate

Теперь мы можем приступить к реализации действий контроллера. Давайте сначала проложим маршруты в router.ex. Я добавлю эти маршруты в конец области / api.

Вы можете переместить сгенерированный room_controller.ex в папку / api рядом с другими контроллерами.

Это первый раз, когда мы используем плагин Guardian в контроллере. Подключаемый модуль EnsureAuthenticated гарантирует, что у нас есть действующий пользователь, поскольку мы реализовали подключаемый модуль VerifyHeader в маршрутизаторе. Если это не удается, он ответит с помощью функции unauthenticated, которая находится в нашем SessionController.

В действии create вы также увидите, что мы получаем доступ к current_user с помощью Guardian. Когда комната создается, мы также хотим, чтобы пользователь присоединился к только что созданной комнате, поэтому сейчас у меня это происходит с помощью assoc_changeset после создания комнаты. Кажется грязным помещать это туда ... в Rails я мог бы поместить это в ActiveRecord :: Base.transaction, но пока это подойдет, и я оставлю это как возможность для рефакторинга.

Действие join создает UserRoom на основе current_user.id и room_id, переданных в params. Я думал о том, чтобы поместить это в контроллер UserRoom для обработки присоединения / выхода из комнат, но пока это будет работать.

Давайте добавим одно действие к пользовательскому контроллеру, чтобы получить список их комнат. Мы также добавим туда плагин Guardian, только для действия rooms.

Вот git-обзор работы серверной части для конечных точек API комнаты

При наличии обновлений нашего внутреннего интерфейса мы сможем создавать комнаты из внешнего интерфейса. Прежде чем мы создадим формы для этого, давайте настроим некоторые действия, которые будут загружать комнаты текущих пользователей, когда они войдут в систему, и создадим боковую панель, похожую на Slack, которая показывает значок для каждой комнаты.

Мы хотим получить эти комнаты после того, как пользователь войдет в систему, поэтому давайте отправим эту функцию в функцию setCurrentUser нашего потока аутентификации.

И создайте новый файл действия rooms.js.

В этом файле есть все действия, необходимые для получения всех комнат, получения комнат текущего пользователя, создания комнаты и присоединения к ней. Теперь нам нужно создать редуктор для обновления хранилища редуксов.

Не забудьте добавить новый редуктор rooms в наш корневой редуктор.

Нам нужно, чтобы наша боковая панель присутствовала на нашей домашней странице и странице нашей комнаты, поэтому давайте добавим этот новый компонент в контейнер приложения. Я также хочу переместить кнопку выхода из системы на боковую панель, поэтому мы переместим функцию handleLogout в приложение. И с нашей текущей настройкой реактивного маршрутизатора нам нужно передать контекст router, чтобы мы могли отправлять перенаправления.

Я также добавил контейнер Room, который будет видом нашей комнаты чата, но пока давайте просто покажем идентификатор, переданный в URL-адресе.

Далее с компонентом боковой панели

Теперь у нас есть боковая панель, которую увидят вошедшие в систему пользователи, и они могут нажать кнопку внизу, чтобы выйти. Но ваш список комнат, вероятно, будет пуст, поэтому давайте добавим форму для создания некоторых и список всех комнат на главной странице.

Сначала я собираюсь проверить git-коммит нашей рабочей боковой панели

Вот наша новая домашняя страница:

Этот новый компонент Home отображает каждую комнату как RoomListItem, давайте создадим этот компонент в отдельном файле.

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

Далее идет NewRoomForm:

Эта форма очень похожа на другие, которые мы создали, например, форму входа в систему, и для ее отправки нужно просто указать имя.

Идите вперед и отправьте форму, и вы увидите новую комнату, созданную в виде значка на левой боковой панели!

Вот последний коммит git со всей работой из части 4

Теперь у нас есть возможность создавать новые чаты и видеть список наших комнат на боковой панели. Но у нас нет крутых функций реального времени, которые делают Phoenix интересным. В части 5 мы изменим это, подключившись к сокетам и каналам, чтобы наша чат-комната заработала.

Прочтите часть 5 или просмотрите живую демонстрацию