問題点
以下の様な物を準備した時に、
field_with_errors
のdiv
が各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>
解決案
- ググったら以下の二択っぽい空気
-
config/application.rb
のconfig.action_view.field_error_proc
でfield_with_errors
を無かったことにする -
config/application.rb
のconfig.action_view.field_error_proc
のhtml_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
最後に
- より良い解決策あれば教えて下さい