4

I have been searching for a way to properly escape LIKE queries in Ruby on Rails. But all the answers suggest to use string interpolation like this:

Post.where("title LIKE ?", "%#{title}%")

Even with Arel people suggest using string interpolation in the same way.

But this has a caveat. If the query contains a % character it will affect the LIKE expression, that means a query like 20% less will cause the results to include posts which title contains anything between 20 and less which is not what I want. What I want is to get all posts which contains 20% less in the title.

I know there is a method called sanitize_sql_like in the ActiveRecord::Sanitization module but it is a protected method and I cannot call it directly.

I could go to the method source on github and copy the code, it's a pretty simple code actually:

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

But I wonder. If Rails already have it, why write it again?

Is there some way to call the method directly? or any other method to escape LIKE queries in Rails.

PD: Back in the old days in CodeIgniter I used a method called escape_like_str to do exactly this. I refuse to believe Rails doesn't have one.

Sergio
  • 223
  • 2
  • 7
  • 6
    `sanitize_sql_like` is the correct way to do this. The fact that it's `protected` does not prevent you from calling it directly from the class context in a class that inherits from ActiveRecord::Base, e.g. in a Rails `scope` lambda, as in this answer: http://stackoverflow.com/questions/5709887/a-proper-way-to-escape-when-building-like-queries-in-rails-3-activerecord/32165883#32165883. If you're having trouble with this, please edit your question to include the code you tried and the exact error message you're getting. – Jordan Running Jan 27 '16 at 18:49
  • Thanks @Jordan. Is there a way to call it from a controller? – Sergio Jan 27 '16 at 20:33
  • 1
    Not directly. You should have very little query logic in your controller, though. – Jordan Running Jan 27 '16 at 20:35

0 Answers0