Railsでモーダルの出し分けを管理する
Railsでモーダルの表示処理をまとめて衝突しないように管理する方法を紹介します。
背景
ツクリンクを運営する中でモーダルが少しづつ増え、衝突することがあったためモーダルの優先順位を付け、衝突しないよう実装をしました。
実装
前提
以下の3つのモーダルがあるとします。
- A: 初回ログインで出すモーダル(全ページ)
- B: 特定のユーザーにだけお知らせを出すモーダル(全ページ)
- C: 特定のページで出すモーダル(Posts#show)
コードサンプル
全ページに出すモーダルはApplicationControllerで該当ユーザーか判断しモーダルに必要な情報をセットします。
# controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :set_modal_A before_action :set_modal_B def set_modal_A return if cookies['modal_A'].present? # 表示済みなら何もしない if is_first_signed_in? # 初回ログインか? @modal_A = { title: '表示に必要な情報など' } end end def set_modal_B return if cookies['modal_B'].present? # 表示済みなら何もしない if show_notice? # お知らせを出すユーザーか? @modal_B = true end end end
Viewごとに出るモーダルは provide
でモーダルをセット
# views/posts/show.html.erb <% provide :modal, render('modal/C') %>
レイアウトのView(もしくはそれに準ずるパーシャル)でモーダルの出し分けを行います。 ifの上位にあるものが優先され、モーダルが複数renderされるのを防いでいます。
# views/layouts/application.html.erb <% if yield(:modal).present? %> <%= yield(:modal) %> <% elsif @modal_B.present? %> <%= render 'modal/B' %> <% elsif @modal_A.present? %> <%= render 'modal/A' %> <% end %>
各モーダルのViewでは表示を管理するCookieを保存するなどの処理をしています。
# views/modal/A.html.erb <% cookies.permanent['modal_A'] = { value: true, expires: 1.day } %> <div class="modal">お知らせだよ!</div>