2010-10-26 3 views
5

Я хочу, чтобы мой код, чтобы сделать две вещи, которые в настоящее время не делаетПомощь с рельсов активной записи запросов (например, п)

@students = Student.where(["first_name = ? OR middle_name = ? OR last_name = ?", params[:query].split]) 
  1. Работа. (он говорит, что им должен пройти 4 параметра, но я хочу, чтобы пользователь мог вводить слова и находить по этим словам в каждом из этих полей и возвращать любые соответствия)

  2. Фактически используйте предложение Like вместо жесткого равного предложения.

Пожалуйста, помогите.

ответ

8

Это похоже на проблему, которая лучше подходит для поиска, а не для SQL. Вы считали что-то вроде thinking sphinx или act as ferret (solr, вероятно, будет излишним).

... если вы должны сделать это в SQL, можно построить что-то вроде этого запроса:

cols = ['first_name', 'last_name', 'middle_name'] 
query = 'John Smith' 
sql_query = cols.map{|c| query.split.map{|q| "#{c} like '?'"}}.join(' OR ') 
sql_query_array = query.split * cols.count 
Student.where(sql_query, sql_query_array) 
+2

+1 для Thinking Sphinx, –

+1

Обратите внимание на SQL-инъекцию. – Reactormonk

+0

Хорошая точка. Представьте, что это просто иллюстрация, но я обновил пример, чтобы быть более безопасным ... в основном я предлагаю использовать поиск. – njorden

4

Я согласен с предыдущим советом, что если вам нужно сделать поиск, вы должны смотреть на что-то вроде Solr или Sphinx.

Во всяком случае, это должно помочь вам.

def search 
    query = params[:query].split.map {|term| "%#{term}%" } 
    sql = "first_name LIKE ? OR middle_name LIKE ? OR last_name LIKE ?" 

    @students = Student.where([sql, *query]) 
end 

Ответ на шаг 1 используют удивительную маленькую особенность Руби называется «пейнтбольный оператор», который позволяет принимать массив и оценить его в качестве списка аргументов.

Ответ на шаг 2 состоит в том, чтобы просто массировать строку запроса, которую вы возвращаете из параметров, и превращать ее в то, что вы можете использовать с оператором LIKE. Я в основном украл это у Railscasts Simple Search Form episode.

+0

Просто пытался использовать оператора «LIKE» и не мог вспомнить, как ваш ответ помог мне совсем немного. Спасибо, Адам. – Tass

1

Я не уверен, если вы хотите, чтобы все поля для поиска и тот же термин, если что является случай, то вы можете сделать это:

where("first_name LIKE :term OR middle_name LIKE :term OR last_name LIKE :term", { term: "%#{params[:term]}%"}) 

Нет необходимости в какой-либо сумасшедший split или map или что-нибудь еще , это просто прямо. ActiveRecord

Смежные вопросы