2014-09-20 108 views
3

我想通過我的Rails應用程序中的名字和姓氏搜索用戶,目前我正在嘗試每種方法都得到混合結果。有沒有辦法重新編寫這些方法來獲得我想要的結果?試圖通過名字和姓氏搜索

user_controller.rb

方法#1

def self.search(query) 
    where("first_name LIKE ? OR last_name LIKE ?", "%#{query}%", "%#{query}%") 
end 

這適用於任何名字或姓氏,但不能同時使用。

方法2

def self.search(keywords) 
    if keywords 
    where(:all, :conditions => ["concat(first_name," ",last_name) like?", "%#{keywords}%"]) 
    end 
end 

這不返回任何結果

方法#3

def self.search(search) 
    if search 
    select('(first_name || " " || last_name) as \'ful_name\', *') 
    where ['first_name LIKE :s OR last_name LIKE :s OR ful_name LIKE :s', :s => "%#{search}"] 
    else 
    scoped 
end 
end 

這將返回錯誤

的SQLite3 ::的SQLException:沒有這樣的列:ful_name:SELECT「users」。* FROM「us ers「WHERE(first_name LIKE'%Spider Man'或last_name LIKE'%Spider Man'或ful_name LIKE'%Spider Man')ORDER BY created_at DESC

app/views/users/index.html.erb:5:在`_app_views_users_index_html_erb__848623016_40254132'

index.html.erb

<% provide(:title, 'Search') %> 
<h1>Search</h1> 

<ul class="span4 users"> 
    <%= render @users %> 
</ul> 

_user.html.erb

<li> 
    <%= image_tag user.avatar(:medium) %> 
    <h4><%= link_to user.full_name, feed_user_path(user), :class => "follow-color" %></h4> 
    <% if current_user.admin? && !current_user?(user) %> 
    | <%= link_to "delete", user, method: :delete, 
            data: { confirm: "You sure?" } %> 
    <% end %> 
</li> 

_header.html。 ERB

<%= form_tag users_path, method: "get", class: "search-bar" do %> 
    <%= text_field_tag :search, params[:search], placeholder: "Search" %> 
<% end %> 
+0

第一varitan看起來是正確的,但你是什麼意思'這適用於名字或姓氏,但不是兩個.'? – IS04 2014-09-20 04:36:53

+0

它將通過我在數據庫中的名字或姓氏字符串進行搜索,但不會爲first_name + last_name搜索 – teddybear 2014-09-20 04:45:55

回答

4

這一個:

:conditions => ["concat(first_name," ",last_name) like?", "%#{keywords}%"] 

不會工作,因爲你有一個(陰險)報價的問題。在Ruby中,這樣的:

"a" "b" 

是一樣的:

"ab" 

所以你:conditions真的是這樣的:

:conditions => ["concat(first_name,,last_name) like?", "%#{keywords}%"] 

你的意思是說:

:conditions => ["concat(first_name, ' ', last_name) like ?", "%#{keywords}%"] 

SQL中的字符串文字使用單引號s,而不是雙引號。另外,如果你使用的是聲稱支持標準的SQL數據庫,你應該使用||操作字符串連接:

:conditions => ["first_name || ' ' || last_name like ?", "%#{keywords}%"] 

第三個不會起作用,因爲在SELECT子句中定義的別名不一般在WHERE子句中可用,因此出現「未知列」錯誤。你也扔掉select調用的結果,所以我想你錯過了在.這裏太:

select('(first_name || " " || last_name) as \'ful_name\', *') 
where ['first_name LIKE :s OR last_name LIKE :s OR ful_name LIKE :s', :s => "%#{search}"] 

還有報價問題的潛力:字符串常量在SQL中使用單引號,雙引號爲標識符。你想,只是說:

where("first_name like :s or last_name like :s or first_name || ' ' || last_name like :s", :s => "%#{search}") 

或者只是:

where("first_name || ' ' || last_name like :s", :s => "%#{search}") 

需要注意幾個問題:

  1. 字符串連接運營商是特定於數據庫。標準SQL使用||,但根據配置,MySQL希望使用concat函數。 AFAIK,SQLite支持很多MySQL-isms,但是當你使用它們時你需要知道,並且你應該儘可能地堅持標準。
  2. 引用是數據庫特有的。標準SQL對於字符串文字使用單引號,對於標識符使用雙引號(例如表名和列名)。 MySQL使用back-ticks作爲標識符,SQLite(AFAIK)可以讓你使用雙引號或者back-ticks標識符和單引號或者雙引號。再次堅持標準儘可能建立良好的習慣。
+0

真的很好的答案! – 2014-09-20 07:04:54

+0

@RichPeck:謝謝。簡單的「做X」答案讓我感覺不對。 – 2014-09-20 18:46:16

+0

你真棒。最後一個工作。 – teddybear 2014-09-21 22:37:39