wvanbergen / scoped_search

Easily search you ActiveRecord models with a simple query language that converts to SQL.
MIT License
265 stars 78 forks source link

has_rich_text relation is not supported #202

Open istvan-ujjmeszaros opened 3 years ago

istvan-ujjmeszaros commented 3 years ago

We are using ActionText::RichText, which is using the has_rich_text relation, but scoped_search doesn't seem to have support for it so we can't search in the content of the rich_text field. Is there any workaround?

istvan-ujjmeszaros commented 3 years ago

If anyone else needs a workaround, I have ended up using this code:

class Snippet < ApplicationRecord
  has_rich_text :content

  scoped_search on: :title
  scoped_search relation: :content, on: :body, ext_method: :find_by_content

  def self.find_by_content(key, operator, value)
    { :conditions => sanitize_sql_for_conditions(["snippets.id IN (SELECT record_id FROM action_text_rich_texts WHERE record_type='Snippet' AND body ILIKE ?)", "%#{value}%"]) }
  end
end

I am leaving this open as it would be great if the gem would have built-in support for has_rich_text relations.

istvan-ujjmeszaros commented 3 years ago

I think this workaround has an SQL injection vulnerability. Can anyone suggest a better way to do this or rewrite this to use a parameter? I had no luck with that.

adamruzicka commented 3 years ago

You should be able to use ? placeholders and sanitize_sql_for_conditions to prevent sql injection. See here

Something along the lines of this could work

class Snippet < ApplicationRecord
  has_rich_text :content

  scoped_search on: :title
  scoped_search relation: :content, on: :body, ext_method: :find_by_content

  def self.find_by_content(key, operator, value)
    value = "%#{value}%"
    sql = "id IN (SELECT record_id FROM action_text_rich_texts WHERE record_type='Snippet' AND body ILIKE ?)"
    { :conditions => sanitize_sql_for_conditions([sql, value]) }
  end
end
istvan-ujjmeszaros commented 3 years ago

Thanks, @adamruzicka, I just couldn't find the sanitizer methods on my own, sanitize_sql_for_conditions seems to work well here, and it is good to know that such methods exist!