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

hotoolong's blog

Railsやvimや気になったことを綴ってます

Rails4.2でlike句のサニタイズをする

2016年はじまってもう2月になってしまいました。 遅ればせながら、あけましておめでとうございます。

昨年から相当ハードなスケジュールでなかなかブログが書けてないですが、 今年はもう少し書く時間を確保したいところ。 頑張ります。。

今日のお題は SQLでLike句を使う場合に RailsActiveRecordを使ってwhere句

Hogehoge.where('name LIKE ?', "%#{args[:name]}%") 

の様な書き方をするケース もしくはscopeでArelに設定して

scope :by_name, ->(name) {
  where(arel_table[:name].matches("%#{name}%"))
}

の様な書き方もよく見かけますが、 like句に対してサニタイズするのを忘れてしまうこともあります。

Rails4.2からサニタイズするメソッドが利用できるようになってます。 http://apidock.com/rails/v4.2.1/ActiveRecord/Sanitization/ClassMethods/sanitize_sql_like

def sanitize_sql_like(string, escape_character = "\\")
  pattern = Regexp.union(escape_character, "%", "_")
  string.gsub(pattern) { |x| [escape_character, x].join }
end

sanitize_sql_likeを使って 先ほどの処理が

Hogehoge.where('name LIKE ?', "%#{sanitize_sql_like(args[:name])}%") 
scope :by_name, ->(name) {
  where(arel_table[:name].matches("%#{sanitize_sql_like(name)}%"))
}

の用に書くことができます。 便利ですね。