☀️

【RailsとBootstrap】フォーム提出時に確認モーダルを出す

2023/06/17に公開

ポートフォリオにタイトル通りの機能を実装しました。
(ポートフォリオ「飲食店共有ルーム」: https://restaurants-we-know.herokuapp.com/ )
学習の一環として一連の作業を記していきます。

前提

ruby (2.7.1)
rails (6.0.6)
bootstrap(4.5.0)

【課題】

  • フォーム提出時に確認モーダルを出すこと
    • 実装方法: bootstrapを使う
  • モーダルにDBから取得したデータを表示すること
    • 実装方法: js.erbを使って非同期で行う

【該当の画面】

  • メンバー申請画面
  • 「部屋」のトークン('Yiw84hBK'のようなランダムな文字列)を入力して送信することで、その「部屋」のメンバー申請を行う
  • (そのトークンは事前に知人から共有されている前提)

【アプリの挙動】

  • token入力・送信 →サーバーでバリデーション

    • バリデーションNG時:バリデーション表示
    • OK時:そのまま画面遷移して申請完了

    [変更点]

    • OK時:モーダルで部屋名と部屋オーナーを表示し、OKorNOを選択 →OKクリックで申請完了

(画面のスクショのビフォーアフターを一番下のパートに載せています!)

実装

手順
  1. ルーティングを作成
  2. コントローラにモーダル表示用のアクションを作成
  3. viewにモーダルを作成
  1. ルーティングを作成
routes.rb
resources :member_requests, only: [:new, :create, :destroy] do
+  collection do
+    post :check
+  end
(略)
end
  1. コントローラにモーダル表示用のcheckアクションを作成
app/controllers/member_requests_controller.rb
()

def check
    if params[:room_token].blank?
      redirect_to new_member_request_path, notice: 'idが入力されていません' 
    else
      if current_user.request_allowed == true
        get_user
        @room = Room.find_by(token: params[:room_token])
        if @room.nil?
          redirect_to new_member_request_path, notice: 'idが間違っています'
        else
          @room_token = params[:room_token]
          @room_founder = User.find(@room.room_founder.founder_id)
        end
      end
    end
  end
end
  1. viewでフォームのオプションを変更・モーダルを作成
app/views/member_requests/new.html.erb
-   <%= form_with url: member_requests_path, local: true do %>
+   <%= form_with url: check_member_requests_path, remote: true do %>
(略)
+ <div class="modal fade" id="confirm_modal" tabindex="-1" aria-hidden="true"></div>

form_withからlocal: trueを消すことで、非同期通信が行われるようになります。
(rails6.0では、form_withはデフォルトで非同期通信となる。そのため本来は上記の追加コードのremote: trueは不要。あっても動くよ)

また、モーダルの一番外のdiv要素をここで追加しています。
後からjs.erbでこの中にモーダルの中身を追加します。

参考: Bootstarap4.5 モーダル
https://getbootstrap.jp/docs/4.5/components/modal/


app/views/member_requests/check.js.erb
$('#confirm_modal')
  .html('<%= j(render('confirm_modal')) %>')
  .modal('show');
app/views/member_requests/_confirm_modal.html.erb
 <div class="modal-dialog" role="document">
  <div class="modal-content">
    <div class="modal-header">
      <h5 class="modal-title">申請先はこちらでよろしいですか?</h5>
      <button class="close" data-dismiss="modal"></button>
    </div>
    <div class="modal-body">
      <span class="modal-inline-text">部屋名: <%= @room.name %></span><br>
      <span class="modal-inline-text">オーナー:  <%= @room_founder.name %></span>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn m-0" data-dismiss="modal">
        キャンセル
      </button>
      <%= link_to "申請する", member_requests_path(room_token: @room_token), method: :post, class: "btn btn-success" %>
    </div>
  </div>
 </div>

check.js.erbは、2のcheckアクションが終わった後に呼び出されるファイルです。
hoge.html.erbのようなファイルと違い、hoge.js.erbの形式のファイルにはjs、JavaScriptを書くことが出来ます。

このファイルでは、new.html.erbで用意した#confirm_modalのdiv要素にモーダルの中身を挿入、さらにそれを表示(show)しています。

ここでいう「モーダルの中身」とは、その下のファイル_confirm_modal.html.erbとなります。

ここのコードは、上に貼ったBootstrapの公式のコードを参考にしたものです。

@room_founderなど、利用者にとって必要な情報を2のcheckアクションで取得しておいたので、モーダルでそれらを表示し、利用者が確認できるようにしています。


変更前のスクショ

誤ったトークンが送信された場合: エラーメッセージが表示される


存在するトークンが送信された場合: (何の確認もなく)申請が完了する



変更後のスクショ

モーダル内に部屋名とオーナーが表示されるのでユーザーが安心できる


感想など

ここでは書いてないけど、Bootstrap導入に手間取った(gem?、yarn?、CDN?)。ただその分webpackerやjsファイルのコンパイルなど、根本部分の知識を深められたのでそれはよかった。


転職を考えている方へ

「転職ドラフト」というサービスを使って、企業から指名を受けてみませんか?

実務1-2年目でも、うまくいけば転職ドラフトで年収数百万UPできるようです(ググると記事が見つかるはず)

登録時に次の紹介コードを入れて、その後レジュメ審査が通過すると、もれなくAmazonギフト券3000円分などのプレゼントがもらえます。

気になっている方はぜひ使ってみてください!

紹介コード:HJGJ

転職ドラフト

https://job-draft.jp/


Bootstrapの導入に際して、最終的にこちらの記事を参考にしました

https://almonta2021blog.com/【rails】rails6にbootstrapを導入する方法/

自分がハマった問題が書いてある記事

bootstrapのCSSの要素のみを使う場合は動いたが、jqueryだったりpopper.jsに依存する要素は正常に作動しなかった。(プルダウン等)

https://qiita.com/en-coding/items/af8bc6ba6bd5d4e49d5a

Discussion