Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

問題点

  • 以下の様な物を準備した時に、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

最後に

  • より良い解決策あれば教えて下さい
andpad
建築施工管理者向けアプリANDPADを開発、運営するスタートアップ
https://tech.andpad.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away