改良中...yen_fieldが欲しい!

業務システムの入力には金額がつきものだ。でも現状では、その度に以下のように書く必要がある。

<%= text_field 'slip', 'total_yen', :value=>number_with_delimiter(@slip.total_yen), :autocomplete=>'off', :style=>"text-align:right"  %>

上記のような長い長いオプションと共に何度も書くのは面倒だ...。できることなら「yen_field 'slip', 'total_yen'」で済ませたい。そこでソースを見て悩んだ結果、以下のようにヘルパーとして登録しておけば、何とか実現できそう。

  • options.merge!でデフォルトのオプションを設定しておくことで、自分好みの便利なフォームに自由に変更することができる。
# ヘルパー: app/helpers/application_helper.rb
module ApplicationHelper
  def yen_field(object_name, method, options = {})
    # object_nameに基づくオブジェクト(モデルのインスタンス)から、methodが示すフィールドの値を取得している。
    # 例: yen_field 'slip', 'total_yen' --> @slip.total_yen が value に設定される。
    object = self.instance_variable_get("@#{object_name}")
    value = object.send(method)
    # デフォルトのオプション設定
    options.merge!(:value=>number_with_delimiter(value), 
                   :autocomplete=>'off', 
                   :style=>"text-align:right")

    ActionView::Helpers::InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("text", options)
  end
end

これで以下のように書けるようになった!シンプルで見やすくなった!

<%= yen_field 'slip', 'total_yen'  %>

忘れがちなこと

このyen_fieldはカンマ区切りの数文字列をそのままパラメーターとして送信するので、受信側のslipモデルでは以下のようにしておかないと(文字列からカンマを除外する)、おかしな数字を受け取ることになる。

  def total_yen=(value)
    self[:total_yen] = value.gsub(/,/, '')
  end
      • この面倒くさいカンマの除外手順を無くす方法ってあるだろうか?