Posted at

Railsのフォームの送信ボタンのi18nの処理をhelperに切り出す

More than 1 year has passed since last update.

Scaffoldで生成される _form.html.erb 等に記述される f.submit は ActionView::Helpers::FormBuilder#submit を呼んでいて、 form_for に与えられた record の状態に応じて update, create, submit の3種類を判別して良い感じに I18n#t を呼んでくれる。

しかし、 submitボタンにFont Awesomeのようなアイコンを表示したい場合に面倒だ。下記の通り I18n#t の引数に与えるキーがprivateメソッドに実装されていてカスタマイズしづらい。

https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/form_helper.rb#L2240-L2256

private

[...]

def submit_default_value
object = convert_to_model(@object)
key = object ? (object.persisted? ? :update : :create) : :submit

model = if object.respond_to?(:model_name)
object.model_name.human
else
@object_name.to_s.humanize
end

defaults = []
defaults << :"helpers.submit.#{object_name}.#{key}"
defaults << :"helpers.submit.#{key}"
defaults << "#{key.to_s.humanize} #{model}"

I18n.t(defaults.shift, model: model, default: defaults)
end

というわけで、コピペ&小改修して下記のとおりi18n関連の処理をhelperとして切り出す。

# @see https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/form_helper.rb#L2240-L2256

module I18nHelper
def i18n_submit_default_value(form)
object = convert_to_model(form.object)
key = object ? (object.persisted? ? :update : :create) : :submit

model = if object.respond_to?(:model_name)
object.model_name.human
else
form.object_name.to_s.humanize
end

defaults = []
defaults << :"helpers.submit.#{form.object_name}.#{key}"
defaults << :"helpers.submit.#{key}"
defaults << "#{key.to_s.humanize} #{model}"
I18n.t(defaults.shift, model: model, default: defaults)
end
end

Viewsでの使い方は以下の通り。

<%= f.button type:'submit' do %>

<%= fa_icon(:save, text:i18n_submit_default_value(f)) %>
<% end %>

ちなみに fa_iconfont-awesome-rails.gem というFont AwesomeをRailsで使いやすくするgemのHelperメソッドです。