Safe ActiveRecord like query
I'm trying to write LIKE query.
I read that pure string quires aren't safe, however I couldn't find any documentation that explain how to write safe LIKE Hash Query.
Is it possible? Should I manually defend against SQL Injection?
To ensure that your query string gets properly sanitized, use the array or the hash query syntax to describe your conditions:
Foo.where("bar LIKE ?", "%#{query}%")
or:
Foo.where("bar LIKE :query", query: "%#{query}%")
If it is possible that the query
might include the %
character and you do not want to allow it (this depends on your usecase) then you need to sanitize query
with sanitize_sql_like
first:
Foo.where("bar LIKE ?", "%#{sanitize_sql_like(query)}%")
Foo.where("bar LIKE :query", query: "%#{sanitize_sql_like(query)}%")
Using Arel you can perform this safe and portable query:
title = Model.arel_table[:title]
Model.where(title.matches("%#{query}%"))
For PostgreSQL it will be
Foo.where("bar ILIKE ?", "%#{query}%")
In case if anyone performing search query on nested association try this:
Model.joins(:association).where(
Association.arel_table[:attr1].matches("%#{query}%")
)
For multiple attributes try this:
Model.joins(:association).where(
AssociatedModelName.arel_table[:attr1].matches("%#{query}%")
.or(AssociatedModelName.arel_table[:attr2].matches("%#{query}%"))
.or(AssociatedModelName.arel_table[:attr3].matches("%#{query}%"))
)
Don't forget to replace AssociatedModelName
with your model name
You can do
MyModel.where(["title LIKE ?", "%#{params[:query]}%"])