hotoolong's blog

プログラムのことやエンジニアリングに関することを記事にしています。

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)}%"))
}

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