2017-04-06 28 views
1

我是Ruby on Rails的新手,因此我对搜索功能有许多问题。Ruby on Rails搜索功能解决方案

搜索查看:

<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> 

控制器:

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

型号:

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 

索引视图:

<% @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 %> 

我的解决方案有效,我没有得到重复,但代码看起来非常糟糕,我不得不说“寻找预先或姓氏”。任何人都可以帮助我提供更好的解决方案。 对我来说,如果你只是在寻找一个学生,并且你不必说出你在找什么(姓或名)并且你没有得到重复,那就完美了。也许学生的名字是“彼得彼得”(不好的例子,但它可能发生^^),所以我只想让彼得在我的Student_array中一次。除此之外,我希望可以选择搜索明确的姓氏,所以如果有学生叫做“Hans-Peter”,学生叫做“Hans”,但我只想找到“Hans”...... 有没有办法用更少更漂亮的代码来实现这个问题?

感谢您的帮助和我的英语不好对不起..我尽我所能:) 再见

回答

0

IMO,你的代码需要一个完整的重构。这是基础,帮助你重构你的搜索逻辑:

# 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 

有女士prename或包含搜索的字符串姓氏不限学生记录将被退回。

你将不得不相应地改变你的控制器的调用搜索方法。

+0

哇!十分感谢!我用你的解决方案,它完美的作品:)如果名称的第一个字母是upcased或不,这很重要,这是非常棒的。 “#{column_name} ILIKE:search”只有一个问题:我必须使用LIKE而不是ILIKE。也许是因为我使用SQLite3?我不确定。 – homior

+0

@homior yes我忘了提及使用的数据库:postgreSQL使用'ILIKE',MySQL和SQLite使用'LIKE'。我很高兴我的代码帮助你,最重要的是你理解逻辑并且可以重现它!使用Rails获得乐趣:) – MrYoshiji

+0

我是我不知道这个“end.join('OR')”究竟在做什么,我知道sql_conditions将是“prename LIKE:search OR lastname LIKE:search”,所以如果你使用这个“end.join('OR') “,它会添加一个'OR',每次他经过循环,除了最后一次?(再次翻英文^^) – homior