一から勉強させてください

最下級エンジニアが日々の学びをアウトプットしていくだけのブログです

Railsのbefore_validationで文字列の先頭、末尾にある全角スペースを取り除く

Strip#stripを使うだけでは半角スペースとか改行文字しか取り除けないので、before_validation時に全角スペースを取り除く方法を考える。

ちなみに Ruby は 2.1.2、Rails は 4.1.0 を前提に書いてます。

auto_strip_attributes の導入

auto_strip_attributesという gem があったのでとりあえず使ってみる。

Gemfile に書いて、bundle installする。

gem "auto_strip_attributes", "~> 2.0"

こうやって使うっぽい。

class User < ActiveRecord::Base

  # Normal usage where " aaa   bbb\t " changes to "aaa bbb"
  auto_strip_attributes :nick, :comment

  # Squeezes spaces inside the string: "James   Bond  " => "James Bond"
  auto_strip_attributes :name, :squish => true

  # Won't set to null even if string is blank. "   " => ""
  auto_strip_attributes :email, :nullify => false
end

これだけでとりあえず半角スペースとかは消せそう。便利!でも全角スペースは消せない。

strip_full_width_space フィルターを追加する

lib/auto_strip_attributes.rbをみた感じ、set_filterで独自フィルターをつくってsetupで追加できるっぽかったのでつくってみる。

config/initializers/auto_strip_attributes.rbをつくって以下のようにする。

AutoStripAttributes::Config.setup do
  set_filter strip_full_width_space: false do |value|
    unless value.nil? || !value.is_a?(String)
      value.remove(/\A[\s ]+|[\s ]+\z/)
    end
  end
end

set_filter strip_full_width_space: false doのとこでデフォルトfalseでフィルターを追加する。実際に使いたいところでstrip_full_width_space: trueにしてやればセットできるようになる。

value.removeactive_support/core_ext/string/filters.rbに書いてあるやつ。gsub pattern, ''をちょっと短く書ける。

正規表現/\A[\s ]+|[\s ]+\z/\A\zは文字列の先頭と末尾を表す。こちらの記事にあるように^$Ruby で使うのは危険だったりするらしい。自分は JavaScript を主に書いていた人間なのでこういう違いには注意しないと。。

[\s ]は半角スペース OR 全角スペースどちらかにマッチ。カッコ内のどれか一文字という意味になる。(この場合、半角スペースは要らないか。。)

モデル側でフィルターを使用する

class User < ActiveRecord::Base

  auto_strip_attributes :nick, :comment, strip_full_width_space: true

end

これで例えば:nickほげとかだったらちゃんとほげにしてくれる。

まとめ

わざわざ gem いれなくてもできそうですが、こんな感じで全角スペースの削除ができました。

auto_strip_attributes.rbのコードは短くて(80 行ぐらい)読みやすかったので Ruby の勉強にも良いと思います。おすすめ。

参考