Как использовать и настраивать сообщения и типы Rails Flash
Для этого проекта нам понадобятся следующие ингредиенты:
- Новый проект Rails 7
rails new flash_msg --css=tailwind --javascript=esbuild
- Ваша любимая IDE
- Создайте шаблон
Post
с помощью следующей команды:rails g scaffold Post title:string msg:text
- Обновите корень, чтобы по умолчанию использовался
posts#index
, добавив следующую строку в файл routes.rbroot "posts#index"
- Запустите миграцию для создания таблицы (в этом проекте используется SQLite, но вы можете перейти на PostgreSQL или MySQL — если да, не забудьте обновить Gemfile или добавить — базу данных при создании проекта на шаге 1)
или просто возьмите исходники с github: https://github.com/spaquet/rails-flash-msg
Давайте сделаем его лучше, так как стандартная конфигурация размещает все элементы в верхней левой части экрана.
Улучшить общий внешний вид:
Приложение.html.erb
<div class="max-w-6xl pt-4 mx-auto"> <%= yield %> </div>
Это горизонтально и равномерно дополнит содержимое и добавит отступ в самом верху, чтобы избежать столкновения с панелью навигации браузера.
Application.tailwind.css
Давайте позаботимся о полях формы. Так как этот компонент будет использоваться везде в приложении, давайте добавим CSS в application.tailwind.css и создадим класс для определения общего стиля для всех полей.
@tailwind base; @tailwind components; @tailwind utilities; @layer components { .form-field { @apply border border-slate-300 focus:border-slate-900 p-2; } }
Теперь нам просто нужно отредактировать часть, используемую формой _form.html.erb
, расположенную в папке app/views/posts.
Тада! Наша форма теперь выглядит немного лучше. По крайней мере, мы можем видеть, где находятся поля:
Давайте теперь сосредоточим наше внимание на флеш-сообщениях.
Вспышка, вспышка и еще раз вспышка
Если вы откроете файл index.html.erb или show.html.erb в каталоге app/views/posts, вы заметите, что их самая первая строка содержит следующий фрагмент кода:
<p style="color: green"><%= notice %></p>
Теперь это немного сокращает, так как отображает только флэш-сообщения типа уведомления. Но перед этим давайте проверим, как срабатывает это сообщение.
Откройте posts_controller.rb в папке app/views/posts и перейдите к методу create или update. .
format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
Как видите, метод redirect_to принимает 2 аргумента. Один — это место для перенаправления, а второй — флэш-сообщение. В этом случае флэш-сообщение имеет тип уведомление и само сообщение, если «Пост был успешно создан»
Флэш-сообщения хранятся в виде хэша, что означает, что их можно идентифицировать как пары ключ-значение.
Имея эту информацию, мы можем написать более общий фрагмент флэш-памяти, который будет обрабатывать больше случаев.
<% if flash.any? %> <% flash.each do |type, msg| %> <div class="py-2 px-4 font-bold msg-<%= type %>"> <%= msg %> </div> <% end %> <% end %>
Удалите <p style="color: green"><%= notice %></p>
из файлов index и show (.html.erb), так как мы будем вызывать наш партиал из application.html.erb файл.
<body> <div class="max-w-6xl pt-4 mx-auto"> <%= render "layouts/flash" %> <%= yield %> </div> </body>
и, конечно, нам нужно добавить немного CSS в application.tailwind.css
.msg-notice { @apply bg-green-300 text-green-900; } .msg-alert { @apply bg-red-300 text-red-900; }
Добавление дополнительных типов флэш-памяти
Теперь у нас есть работающее флэш-решение для отображения типов уведомлений и предупреждений. Допустим, мы хотим добавить информационный тип сообщения. Итак, поскольку Flash — это Hash, наша первая интуиция должна заключаться в том, что мы можем добавить их прямо при вызове команды flash, что-то вроде flash[:custom_type]="Message to be displayed"
Ну, и да, и нет. Это сработает во многих случаях, но не при использовании метода redirect_to, как указано в: https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/flash.rb.
Пример:
Давайте добавим собственный стиль CSS в файл application.tailwind.css.
.msg-custom { @apply bg-yellow-300 text-yellow-900; }
а затем измените метод create файла posts_controller.rb следующим образом:
# POST /posts or /posts.json def create @post = Post.new(post_params) respond_to do |format| flash[:custom]= "Post was successfully created / Custom message" if @post.save format.html { redirect_to post_url(@post), success: "Post was successfully created." } format.json { render :show, status: :created, location: @post } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @post.errors, status: :unprocessable_entity } end end end
У нас будет текст «Сообщение успешно создано / Пользовательское сообщение», выделенное желтым цветом на светло-желтом фоне, как только мы создадим новое сообщение, но текст для типа успеха никогда не будет отображаться как Метод redirect_to не разрешает этот тип.
Как мы можем это исправить?
Согласно комментарию в https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/flash.rb нам нужно объявить наши пользовательские стили, добавив их в список в ApplicationController. .
class ApplicationController < ActionController::Base add_flash_types :success, :warning, :info end
В приведенном выше коде мы определяем 3 новых типа: success, warning и info, которые можно использовать в redirect_to метод.
Следующий код теперь будет работать должным образом (после определения соответствующего стиля CSS в файле application.tailwind.css).
# POST /posts or /posts.json def create @post = Post.new(post_params) respond_to do |format| if @post.save format.html { redirect_to post_url(@post), success: "Post was successfully created." } format.json { render :show, status: :created, location: @post } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @post.errors, status: :unprocessable_entity } end end end
Что с рендером?
При вызове render мы остаемся на той же странице. Итак, если нам нужно отобразить ошибку во флэш-сообщении, вызвав flash[:error]="Сообщение об ошибке". Поскольку перенаправления нет, сообщение об ошибке отображаться не будет…
Вот почему существует метод .now, который вызывает flash.now[:error]=”Сообщение об ошибке”. есть, чтобы исправить это. Используя .now, поместите сообщение во флэш-хеш и удалите его, чтобы сообщение не отображалось дважды.
Имейте в виду, что не отображая страницу, вызываемую в redirect_to, флэш-сообщение останется в хэше. Это потенциально означает, что ваши пользователи могут получать противоречивые флэш-сообщения.
Следующее: использование турбо и стимулирования для улучшения отображения флэш-сообщений.