Я пытаюсь создать фильтр для класса Article, который использует SQL-запрос, построенный на лету, на основе параметров, представленных в форме HTML. Поскольку у меня есть несколько отношений «многие ко многим», я не могу использовать Article.where (я так не думаю). Хотя следующий код работает, я не уверен, является ли это наиболее эффективным способом выполнения этого запроса и насколько он безопасен. Я пытаюсь защитить SQL-инъекцию, используя? ключевое слово в строке sql (соглашение la la Rails), но хотелось бы убедиться, что этого будет достаточно. Любой совет, как я могу сделать это более элегантным?Создание настраиваемого метода фильтрации в Rails/SQL
def self.filter(hash)
hash.delete_if {|k,v| v == ""}
hash[:writer_type] = (hash[:writer_type]) if hash[:writer_type] != nil
sql_base = "select distinct articles.* from articles
join tags
on tags.article_id = articles.id
join categories
on tags.category_id = categories.id
left outer join itineraries
on itineraries.article_id = articles.id
left outer join cities
on itineraries.city_id = cities.id
join users
on users.id = articles.user_id"
condition_array = []
key_array = []
hash.each_key {|key| key_array << key}
key_array.each_with_index do |key, i|
operator = "and"
operator = "where" if i == 0
case key
when :writer
sql_base << "\n#{operator} users.username like ?"
condition_array << hash[:writer]
when :writer_type
sql_base << "\n#{operator} users.status in (?)"
condition_array << hash[:writer_type]
when :city
sql_base << "\n#{operator} cities.name like ?"
condition_array << hash[:city]
when :category
sql_base << "\n#{operator} categories.name like ?"
condition_array << hash[:category]
end
end
sql_array = [sql_base,condition_array].flatten
articles = Article.find_by_sql(sql_array)
articles
end