2011-05-27 101 views
3

我試圖創建一個與用戶名稱匹配的「搜索框」。Rails:通過姓名和姓氏進行有效搜索

難度在於用戶同時擁有名字和姓氏。每個人可以有他們的空間(例如「喬恩/邦喬維」,或「尼爾帕特里克/哈里斯」),我想知道最有效的方式,以確保搜索進行連接的兩個名字和姓氏字段。

用戶列表很大,所以性能是一個問題。我可以在用戶模型中拋出一個「全名」def,但我懷疑這不是明智的舉動。我對多欄目索引的瞭解很薄弱,但我懷疑有一種方法可以通過索引來實現,它裏面有一個「」。

只是爲了澄清,我不需要模糊匹配 - 完全匹配只是罰款...我只是需要它在兩個領域的串聯運行。

乾杯......

回答

4

你可以在你的數據庫與普通索引稱爲full_name創建一個新的字段,然後使用一個回調來填充這個每當記錄保存/更新:

before_save :populate_full_name 

protected 

def populate_full_name 
    self.full_name = "#{first_name} #{last_name}" 
end 
2

如果您可以修改數據庫,您可以也應該使用由gjb提供的解決方案。

下面是而不是要求您更改數據庫的解決方案。簡單地收集您可以從搜索框中獲得的所有可能的名/姓對。一些代碼:

# this method returns an array of first/last name pairs given the string 
# it returns nil when the string does not look like a proper name 
# (i.e. "Foo Bar" or "Foo Bar Baz", but not "Foo" or "Foo " 
def name_pairs(string) 
    return nil unless string =~ /^\w+(\s+\w+)+$/ 
    words = string.split(/\s+/) # split on spaces 
    result = [] 
    # in the line below: note that there is ... and .. in the ranges 
    1.upto(words.size-1) {|n| result << [words[0...n], words[n..-1]]} 
    result.collect {|f| f.collect {|nm| nm.join(" ")}} 
end 

此方法提供兩個元件陣列,它可以用於創建or查詢的陣列。下面是該方法的樣子:

#> name_pairs("Jon Bon Jovi") 
=> [["Jon", "Bon Jovi"], ["Jon", "Bon Jovi"]] 
#> name_pairs("John Bongiovi") 
=> [["John", "Bongiovi"]] 
#> name_pairs("jonbonjovi") 
=> nil 

當然,這種方法並不完美(它不大寫的名字,但你可以拆分後這樣做),並可能是在速度方面不是最佳的,但它作品。您也可以重新打開String並在該處添加該方法,因此您可以使用"Jon Bon Jovi".name_pairs