Railsのバリデーションエラーで、「field_with_errors」によるレイアウト崩れを防ぐ
はじめに
自分が使用していたもののバージョンです。
- Ruby ver 2.6.3
- Rails ver 5.2.3
- bootstrap ver 4.3.1
またバリデーション処理が途中の状態なので、色々気になる箇所があるかもしれませんが、流してください。
現象
Rails のフォームを作成してバリデーションエラーを表示させるときに、入力欄のレイアウトが崩れるという現象が発生しました。
これは、Rails が自動的に field_with_errors クラスを持つ div タグで、label タグや input タグを囲むことによって発生したものでした。
Railsでは、エラーメッセージを含むフィールドは自動的にfield_with_errorsクラスを持つdivタグで囲まれます。これを利用して、エラーメッセージをもっと目立たせるようにcssルールを定義しても構いません。
解決方法
解決方法は、2 つあります。
1. 自動挿入されないようにする
2. 挿入されたクラスのスタイルを編集する
この 2 つのどちらを選ぶかは、エラーメッセージが出るだけで十分であるなら前者で、エラーを目立たせるようなスタイルを当てたければ後者がいいと思います。
自動挿入されないようにする
まず 1 つ目は、Railsが自動で挿入しないように、設定をファイルに記述すればOKです。
config/application.rb
に以下を追加しましょう。
module SampleApp
class Application < Rails::Application
# 他省略..
config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag }
end
end
上記を追加したら、サーバーを再起動させて再度確認してみると、レイアウトが崩れずにエラーメッセージが出るようになりました。
しかし、これでは Rails が提供してくれている機能を自ら使えなくしてしまいます。
そこで、2 つ目のやり方です。
挿入されたクラスのスタイルを編集する
結論から言うと、追加されたクラスにCSSでスタイルを当てるだけです。
そもそもこの機能は、バリデーションでエラーとなった箇所にクラスを挿入し、そのクラスにエラーを目立たせるスタイルを当てるようにと Rails が用意してくれているものです。
まずはレイアウトの崩れを修正します。
スタイルを記述しているファイルに以下を追記してください。
なお今回は、SASS を使用した例で説明していきます。
.field_with_errors {
display: contents;
// もしくは diplay: inline;
}
自分が作成したフォームでは「diplay: contents;」でできましたが、レイアウトによっては、「diplay: inline;」で修正できるかもしれません。
検証ツールを開いて、試してみてください。
次に入力欄の枠が赤色になるようにスタイルを記述します。
Bootstrap3の場合
field_with_errors クラスに対して Bootstrap3 の .has-error
を extend することで入力欄を赤枠で表示さることができます。
.field_with_errors {
display: contents;
@extend .has-error;
}
Bootstrap4の場合
Bootstrap4 の場合は、.has-error
が無くなっているので extend できません。
代わりに input タグに対して .is-invalid
を extend します。
.field_with_errors {
display: contents;
input {
@extend .is-invalid;
}
}
上記を追記したらブラウザで確認してみてください。
このようにレイアウトも修正され、バリデーションエラーが発生した入力欄の枠が赤くなったら成功です。
まとめ
Rails のバリデーション機能によって「field_with_errors」クラスの div タグが挿入されたので、その機能を止めるかレイアウトを修正することで解決できました。
同じ現象に立ち会った人の役に立てればいいなと思います。
Discussion