2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsでモーダルの出し分けを管理する

Last updated at Posted at 2020-05-01

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>

※こちらの記事は自ブログからの転載です
https://akinov.hatenablog.com/entry/2020/05/01/222151

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?