before_validation コールバック関数に引数を持たせる

やりたいこと

電話番号入力欄で後ろに半角、全角スペースがあった時に空白を取り除いてからvalidationを行いたい時に、before_validationを使って書きました。
電話番号だけじゃなくメール入力欄など他の場面でも利用できると思いmoduleを使って書いた時に詰まった部分があったのでどうすればいいか共有します。

とりあえずapp/models/user.rbに下記のように最初は書いていました。

app/models/user.rb
class User < ActiveRecord::Base
# ... 省略 ...

  before_validation :trim_space

  def trim_space
    self.phone.gsub!(/[ \p{blank}\r\t\n\f]/, "")
  end

end

gsub!なのですが!を使ってオブジェクトの状態を変更しておかないと返り値が全角、半角を取り除いた状態にならないので!を使うかもしくは下記のような書き方にしてみてください

app/models/user.rb
  self.phone = self.phone.gsub(/[ \p{blank}\r\t\n\f]/, "")
  return self.phone


これでまずは電話番号の入力欄だけは全角、半角を取り除けるのですが、他にも使いたい時に何度も同じコードを書かなければならないのでmoduleに書いて呼び出すようにしてみました。

app/model/validate_common.rb

module ValidateCommon
  extend ActiveSupport::Concern
  included do
    def trim_space
      self.phone.gsub!(/[ \p{blank}\r\t\n\f]/, "")
    end
  end
end
app/model/user.rb
class User < ActiveRecord::Base
  include ValidateCommon
  # ... 省略 ...

  before_validation :trim_space
end

ただこのままだと電話番号にしか使用出来ない状態なので、app/model/user.rbの:trim_spaceに引数を持たそうとした時につまりました。

app/model/user.rb
class User < ActiveRecord::Base
  include ValidateCommon
  # ... 省略 ...

   before_validation -> {trim_space("phone", "email")}
end

このようにして書けば引数をもたせる事ができるので、DRYなコードにできるかと思います。
app/model/validate_common.rb側も少し編集します。

module ValidateCommon
  extend ActiveSupport::Concern
  included do
    def trim_space(*target_columns)
      target_columns.each do |target_column|
        if self.send(target_column)
          self.send(target_column).gsub!(/[ \p{blank}\r\t\n\f]/, "")
        end
      end
    end
  end
end

条件分岐の部分なのですが、 self.send(target_column)がnilの場合つまり今回だと電話番号、メール入力欄が何も入ってこない場合だとNoMethodError Exception: undefined method `gsub!' for nil:NilClassになるので書いています。

before_validationで書く時は基本シンボルの書き方でメソッドを書いていたので結構詰まりました。
後、sendメソッドのレシーバの持っているメソッドを呼び出すというのも知らなかったので非常に学びがありました。
他にも良い書き方あれば教えて欲しいです。