2017-04-06 12 views
1

Ich bin neu bei Ruby on Rails, daher habe ich mehrere Fragen zu meiner Suchfunktion.Ruby on Rails Suchfunktionslösungen

Suche:

<p> 
<%= form_tag students_path, :method => 'get' do %> 
<p> Advanced_search: <%= check_box_tag "advanced_search", value = "1" %> </P> 
<%= select_tag(:attribute, options_for_select([['Prename',0],['Lastname',1]])) %> 
<%= text_field_tag :search%> 
<%= submit_tag "Search"%></p> 

Controller:

def index 
    @stud = Student.search(params[:search], params[:advanced_search], params[:attribute]) 
end 

Modell:

def self.search(search, advanced_search, attribute) 
    ary = [] 
    if advanced_search 
     case attribute 
     when '0' 
      ary << Array(where(Student.arel_table[:prename].matches("%#{search}%"))) 
     when '1' 
      ary << Array(where(Student.arel_table[:lastname].matches("%#{search}%"))) 
     else 
      raise ArgumentError, 'Something strange happened! problem with select_tag in the search function' 
     end 
    elsif search 
     case attribute 
     when '0' 
      ary << Array(where(prename: search)) 
     when '1' 
      ary << Array(where(lastname: search)) 
     else 
      raise ArgumentError, 'Something strange happened! problem with select_tag in the search function' 
     end 
    else 
     Student.all 
    end 
    ary 
end 

Übersicht:

<% @stud.each do |student_arr|%> 
    <% student_arr.each do |student| %> 
    <li> <%= student.prename + " " + student.lastname + " " + student._format_birthday + " DaZ: " + student.daz.to_s%> 
    (<%= link_to "Details", action: "detail", id: student.id %>) 
    (<%= link_to "Edit", action: "edit", id: student.id %>) </li> 
<% end %> 
<% end %> 

Meine Lösung funktioniert, ich bekomme keine Duplikate, aber der Code sieht wirklich schlecht aus und ich muss sagen "suche nach pre ODER Nachname". Möge mir jemand mit einer besseren Lösung helfen. Für mich wäre es perfekt, wenn du nur nach einem Studenten suchst und du nicht sagen musst, wonach du suchst (Vor- oder Nachname) und du bekommst keine Duplikate. Vielleicht ist ein Student Name "Peter Peter" (schlechtes Beispiel, aber es könnte passieren ^^), also möchte ich Peter nur einmal in meinem Student_array bekommen. Außerdem hätte ich gerne die Möglichkeit, nach einem expliziten Vornamen zu suchen, also wenn Student heißt "Hans-Peter" und Student heißt "Hans" aber ich will nur "Hans" finden ... Gibt es einen Weg dazu Realisieren Sie diese Probleme mit weniger und schöner Code?

Vielen Dank für Hilfe und sorry für mein schlechtes Englisch .. Ich bin mein Bestes tun :) Bye Bye

Antwort

0

IMO, müssen Sie den Code ein komplettes Refactoring. Hier ist die Basis, um Ihre Suchlogik Refactoring:

# student.rb 
def self.search(searched_string) 
    searchable_columns = %w(prename lastname) 
    sql_conditions = searchable_columns.map do |column_name| 
    "#{column_name} ILIKE :searched_string" 
    # use ILIKE if you are using PostgreSQL 
    # use LIKE if you are using MySQL or SQLite 
    end.join(' OR ') 
    where(sql_conditions, searched_string: "%#{searched_string}%") 
end 

Student Rekord mit Vornamen oder Nachnamen der Zeichenfolge enthält, gesucht wird zurückgegeben.

Sie müssten den Aufruf Ihres Controllers entsprechend zur Suchmethode ändern.

+0

Wow! Vielen Dank! Ich habe deine Lösung benutzt und es funktioniert perfekt :) Es spielt keine Rolle, ob der erste Buchstabe des Namens hochgeladen ist oder nicht, das ist ziemlich toll. Es gab nur ein Problem mit der Zeile "" # # column_name} ILIKE: search ".. Ich musste LIKE anstelle von ILIKE verwenden. Vielleicht weil ich SQLite3 verwende? Ich bin mir nicht sicher. – homior

+0

@homior ja, ich habe vergessen, das zu erwähnen DB benutzt: postgreSQL benutzt 'ILIKE', MySQL und SQLite verwenden 'LIKE'. Ich bin froh, dass mein Code-Helfer dir am wichtigsten ist, dass du die Logik verstehst und sie reproduzieren kannst! Viel Spaß mit Rails :) – MrYoshiji

+0

Ich bin Ich weiß nicht, was das "end.join ('OR')" genau macht. Ich weiß, dass sql_conditions "vorname LIKE: search ODER lastname LIKE: search" sind. Also wenn du dieses "end.join ('OR') verwendest ", es wird ein ODER hinzugefügt, jedes Mal, wenn er die Schleife durchläuft, außer beim letzten Mal? (sry für Englisch wieder ^^) – homior