LoginSignup
55
35

More than 5 years have passed since last update.

Rails 5.1のform_withでViewにvalidationエラー表示

Posted at

Rails5.1でform_tagとform_forがform_withに統合されました。
form_withを使ってformを書いたところちょっとした落とし穴があったので共有します。

問題 : validationエラーがviewに表示されない

例えばこんな感じでviewとcontrollerを書いてると、
validationエラーでsaveできなかった時に:newのviewにエラーが表示されません。

new.html.erb
...前略...

<%= form_with model: @user do |f| %>

  <!-- createに失敗するとエラー表示 -->
  <% if @user.errors.any? %>
    <div class="alert alert-danger">
      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

    ...中略...

<% end %>
users_controller.rb
class EventsController < ApplicationController

  # ...中略...

  def create
    @user = User.new(user_params)
    if @event.save
      redirect_to @event, notice: '作成しました'
    else
      render :new
    end
  end

  # ...中略...
end

原因 : form_withはデフォルトでremote: trueになっている

form操作をAjaxで行い時に、form_tag / form_forだとオプションにremote: trueを指定するだけで対応してくれましたが、
form_withでは何も指定しない場合デフォルトでremote: trueになるようです。
(参考)Ruby on Rails 5.1.2 Module ActionView::Helpers::FormHelper#form_with

解決策 : form_withのオプションでlocal: trueを指定

form操作をAjaxで処理したいわけでもないなら、
form_withのオプションでlocal: trueを指定することでエラーメッセージをviewに表示できます。

new.html.erb
...前略...

<%= form_with model: @user, local: true do |f| %>

  <!-- createに失敗するとエラー表示 -->
  <% if @user.errors.any? %>
    <div class="alert alert-danger">
      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

    ...中略...

<% end %>
55
35
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
55
35