読者です 読者をやめる 読者になる 読者になる

プログラミング 美徳の不幸

Ruby, Rails, JavaScriptなどのプログラミングまとめ、解説、備忘録。

カンマ入ったり全角入った数字(の文字列)を数値にしたいやつ

タイトルのやつ自体はrubyだとカンタンなんだけど、適当にこういうクラス作って

module Bacchus
  class IntegerFilter
    def initialize(num_string)
      @num_string = num_string
    end

    def convert
      unless @num_string.is_a?(String)
        return @num_string
      end

      @num_string = @num_string.tr("0-9",  "0-9").gsub(/,||/, '')
      n = @num_string.to_i
      if n == 0 && !['0', 0].include?(@num_string)
        @num_string
      else
        n
      end
    end
  end
end

数字っぽい文字列なら数値にして、それ以外はそのまま戻すコードを用意しておく。 (なんか汚いな、最近エレガントな興味書こうみたいな意欲が全くなくなった気がする...。'hoge'.to_iが0になるの、チェックの仕方これしかないのかな)

問題はウェブアプリケーションでこれをどこに置きますかっていう話。

クラウド家計簿サービスはこういうのとか、空文字列をnilに変換する処理をわりとRackなのかスーパークラスなのか、とにかく低層の共通処理においてしまったがためにわりと標準の仕組み的にうまくいかないことが増えて負債化してしまったらしい。

一見モデルのbefore_saveあたりに置けば良さそうだけど、Int型のItem#priceとかのカラムに文字列'12,345'を突っ込んだ時点でRailsが12にしちゃうのでそれはできない。

というわけでcontrollerで

  def hoge_params
    _params = params.require(:hoge).permit(*Hoge::ACCESSIBLE_ATTRIBUTES)
    [:price, :item_number].each do |attr|
      _params[attr] = Bacchus::IntegerFilter.new(_params[attr]).convert
    end

    _params
  end

が無難かなぁ・・・と思いつつこれが頻出するのは嫌だよね。 なんか良いやり方思いついたら教えて下さい。