【Rails】Ajax コメント機能にバリデーションエラーメッセージを表示する

Ruby on Railsアイキャッチ画像

目標物はこちら

このようにバリデーションのエラーメッセージが表示されるようにする。

コントローラー

  def create
    @product = Product.find(params[:product_id])
    @product_contact = @product.product_contacts.build(product_contact_params)
    respond_to do |format|
      if @product_contact.save
        format.js { render :index }
      else
        format.js { render :error }
      end
    end
  end

バリデーションエラーの場合はjsのerrorにレンダリングさせる。

jsのerrorファイル

$("#contact_messages-error").html("<%= j(render 'layouts/error_messages', model: @product_contact) %>");

これにより、パーシャル化したerrorファイルの変数modelに@product_contactを入れ、_error_messages.html.erbのファイルの情報を取得し、viewのid=”contact_messages-error”の部分を書き換える。

jsでの書き換えエリアの設定とエラーメッセージviewへのレンダリング

エラーメッセージを表示する箇所にrenderを追加

    <div id="contact_messages-error">
      <%= render 'layouts/error_messages', model: form.object %>
    </div>

この、id=”contact_messages-error”で囲った部分をjsで置き換わるようにする。

全体としてはこんな感じ

<%= form_with(model: [product, product_contact]) do |form| %>

<!--デフォルトのエラー文 この部分を共通化するため別ファイルに移す-->
<%
=begin %>
    <% if product_contact.errors.any? %>
      <div id="error_explanation">
        <h2><%= pluralize(product_contact.errors.count, "error") %> prohibited this comment from being saved:</h2>
        <ul>
        <% product_contact.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
        </ul>
      </div>
    <% end %>
<%
=end %>
  <div id="contact_messages-error">
    <%= render 'layouts/error_messages', model: form.object %>
  </div>

  <h6 class="message_label">
    <%= form.label t("views.title.contact_message") %>
  </h6>
  <div class="row message_form_area">
    <span class="field message_box">
      <%= form.text_area :contact_message, style: "width:100%", placeholder: "#{@product.name}についてのメッセージ" %>
    </span>

    <span class="actions">
      <button name="button" type="submit" class="btn massage_btn">
      <i class="far fa-paper-plane fa-lg"></i>
      </button>
    </span>
  </div>

<% end %>

ちなみにform_withは、local: trueをつけるとhtmlファイルを、local: trueをつけないとjsファイルを探しに行く

エラーメッセージviewファイル作成

<% if model.errors.any? %>
  <div class="alert alert-danger">
    <ul class="list-unstyled">
      <h5><%= model.errors.count %>件のエラー</h5>
      <% model.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

エラーメッセージのページをパーシャル化した。

参考記事

[Rails]コメント機能を非同期通信(Ajax)、ついでにエラーメッセージとフラッシュメッセージも非同期化 - Qiita
#はじめにコメント機能を非同期にしていく中で、投稿、削除は非同期にできたけど、バリデーションをかけた場合のエラーメッセージ、フラッシュメッセージの表示まで解説した記事がなかなか見つからなくて、時間…

コメント