読者です 読者をやめる 読者になる 読者になる

naichi's lab

3日後の自分(他人)への書き置き

Rails、form_forが勝手に吐き出す<div class="field_with_errors"></div>を制御する

Ruby on Rails 4

RailsでWebサイトを作ってるんだけどフォームのバリデーション時にレイアウトが崩れて困った。

原因はform_forが勝手に出力する<div class="field_with_errors"></div>ってことがわかったので対応方法をメモ。

環境

  • Rails 4.2.2

事の発端

こんな感じのページがあって、 f:id:naichilab:20160115010042p:plain そのまま送信すると当然バリデーションエラーが起こる。

バリデーション引っかかるのは当然なんだけどなぜかレイアウトが崩れた。 f:id:naichilab:20160115010252p:plain

原因

前後のHTMLを見比べてみると。

崩れる前

(一部抜粋)
          <section>
            <div class='row'>
              <label class="label col col-4" for="user_ユーザー名">ユーザー名</label>
              <div class='col col-8'>
                <label class='input'>
                  <i class="icon-prepend fa fa-user"></i>
                  <input placeholder="exampleuser" type="text" name="user[name]" id="user_name" />
                </label>
              </div>
            </div>
          </section>

崩れた時

(一部抜粋)
          <section>
            <div class='row'>
              <label class="label col col-4" for="user_ユーザー名">ユーザー名</label>
              <div class='col col-8'>
                <label class='input'>
                  <i class="icon-prepend fa fa-user"></i>
                  <div class="field_with_errors"><input placeholder="exampleuser" type="text" value="" name="user[name]" id="user_name" /></div>
                </label>
              </div>
            </div>
          </section>

謎の<div class="field_with_errors"></div>が作られてますなぁ。

ちなみにレイアウトテンプレートはこんな感じ。当然<div></div>なんて囲んでません。

(一部抜粋)
          <section>
            <div class='row'>
              <%= f.label 'ユーザー名', class: 'label col col-4' %>
              <div class='col col-8'>
                <label class='input'>
                  <i class="icon-prepend fa fa-user"></i>
                  <%= f.text_field :name, placeholder: 'exampleuser' %>
                </label>
              </div>
            </div>
          </section>

調査

Rails をはじめよう | Rails ガイド

Railsでは、エラーメッセージを含むフィールドは自動的にfield_with_errorsクラスを持つdivタグで囲まれます。これを利用して、エラーメッセージをもっと目立たせるようにcssルールを定義しても構いません。

なんておせっかいなんだw

対応方法

Configuring Rails Applications — Ruby on Rails Guides

config/application.rbにあるApplicationクラス内に下記を記述すればいいみたい。

    config.action_view.field_error_proc = Proc.new do |html_tag, instance|
      %Q(#{html_tag}).html_safe
    end

直った。 f:id:naichilab:20160115010042p:plain めでたしめでたし。

まとめ

他にも

  • divじゃなくてspanで囲むようにする
  • cssでなんとかする

とか色々やりようがあるみたい。

今回はsky-formsってやつを使うためにHTMLべたべた並べてるので邪魔なdivは生成しないようにした。

色々あるねぇ。