2010-10-26 10 views
5

chcę mojego kodu zrobić dwie rzeczy, które obecnie nie robiPomoc z szyn aktywnych zapytań rekordu (jak klauzuli)

@students = Student.where(["first_name = ? OR middle_name = ? OR last_name = ?", params[:query].split]) 
  1. Work. (mówi, że mam przekazać 4 parametry, ale chcę, aby użytkownik mógł wpisywać słowa i znajdować te słowa na każdym z tych pól i zwracać je).

Proszę o pomoc.

Odpowiedz

8

To wygląda na problem, który lepiej pasowałby do wyszukiwania niż SQL. Czy rozważałeś coś takiego jak thinking sphinx lub act as ferret (solr prawdopodobnie byłoby przesadą).

... jeśli trzeba to zrobić w SQL, można zbudować coś takiego zapytania:

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 dla Thinking Sphinx, –

+1

Zwróć uwagę na iniekcję SQL. – Reactormonk

+0

Dobra uwaga. Pomyślałem, że jest to tylko ilustracja, ale ja zaktualizowałem ten przykład, aby być bezpieczniejszym ... w większości przypadków sugeruję użycie wyszukiwania. – njorden

4

zgadzam się z poprzedniej rady, jeśli trzeba zrobić szukać należy spojrzeć na coś podobnego Solr lub Sphinx.

W każdym razie powinno ci to pomóc.

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 

Odpowiedź na etapie 1 używając niesamowite mało funkcji Ruby o nazwie „operator ikona”, która pozwala wziąć tablicę i ocenić go jako lista argumentów.

Odpowiedzią na krok 2 jest tylko masowanie ciągu zapytania, który otrzymasz z params, i przekształcenie go w coś, czego możesz użyć z operatorem LIKE. Zasadniczo ukradłem to z Railscasts Simple Search Form episode.

+0

Próbowałem po prostu użyć operatora "LIKE" i nie mogłem sobie przypomnieć, jak, twoja odpowiedź pomogła mi całkiem sporo. Dzięki, Adam. – Tass

1

Nie jestem pewien, czy chcesz wszystkie pola, aby szukać tego samego terminu, jeżeli jest sprawa to można to zrobić:

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

Nie potrzeba żadnych szalony split lub map lub cokolwiek innego , to jest po prostu prosta ActiveRecord

Powiązane problemy