LoginSignup
6
3

More than 5 years have passed since last update.

Rails の radio_button のエラーがとても出しにくい

Posted at

問題点

  • 以下の様な物を準備した時に、field_with_errorsdivが各radio_buttonに書かれてしまう

  • new.html.slim

form_for @gessy0129 do |f|
  - Gessy0129.statuses.each do |key, val|
    = f.radio_button :status, key
    label for="gessy0129_status_#{key}"
      = t("activerecord.gessy0129.status.#{key}")
  • app/model/gessy0129.rb
  enum status: {
    open:  1,
    close: 2,
    deny:  3
  }

  validates :status,
    presence: true
  • 通常時のHTML
<form action="/gessy0129">
  <input type="radio" value="open" name="gessy0129[status]" id="gessy0129_status_open" />
  <label for="gessy0129_status_close">有効</label>
  <input type="radio" value="close" name="gessy0129[status]" id="gessy0129_status_close" />
  <label for="gessy0129_status_open">無効</label>
  <input type="radio" value="deny" name="gessy0129[status]" id="gessy0129_status_deny" />
  <label for="gessy0129_status_deny">拒否</label>
</form>
  • エラー時のHTML
<form action="/gessy0129">
  <div class="field_with_errors">
    <input type="radio" value="open" name="gessy0129[status]" id="gessy0129_status_open" />
  </div>
  <label for="gessy0129_status_close">有効</label>
  <div class="field_with_errors">
    <input type="radio" value="close" name="gessy0129[status]" id="gessy0129_status_close" />
  </div>
  <label for="gessy0129_status_open">無効</label>
  <div class="field_with_errors">
    <input type="radio" value="deny" name="gessy0129[status]" id="gessy0129_status_deny" />
  </div>
  <label for="gessy0129_status_deny">拒否</label>
</form>

解決案

  • ググったら以下の二択っぽい空気
  1. config/application.rbconfig.action_view.field_error_procfield_with_errorsを無かったことにする
  2. config/application.rbconfig.action_view.field_error_prochtml_tagで分岐

ただ、

  • 全部消すのは影響デカイのでなし
  • html_tagでの分岐は正規表現書くのが面倒

という理由により別方策を検討してみました

検討結果

hiddenの時にfield_with_errors が出てないのに着目
actionview/lib/action_view/helpers/active_model_helper.rb

の制御をモンキー・パンチすればいいんじゃね!?

解決済みプログラム

  • config/initializers/action_view_helpers.rb
module ActionView
  module Helpers
    module ActiveModelInstanceTag
      def tag_generate_errors?(options)
        (options['type'] != 'hidden' && options['type'] != 'radio')
      end
    end
  end
end

最後に

  • より良い解決策あれば教えて下さい
6
3
1

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
6
3