[英]Rails ActiveRecord - Search on Multiple Attributes
我正在實現一個簡單的搜索功能,它應檢查username,last_name和first_name中的字符串。 我在舊的RailsCast上看過這個ActiveRecord方法:
http://railscasts.com/episodes/37-simple-search-form
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
但是我如何設置它以便在name,last_name和first name中搜索關鍵字並返回記錄,如果其中一個字段與該術語匹配?
我也想知道RailsCast上的代碼是否容易進行SQL注入?
非常感謝!
我假設您的模型名稱是Model - 只需在執行實際查詢時將其替換為您的真實模型名稱:
Model.where("name LIKE ? OR last_name LIKE ? OR first_name LIKE ?", "%#{search}%","%#{search}%","%#{search}%")
關於你對SQL注入的擔憂 - 兩個代碼片段都不受SQL注入的影響。 只要你沒有直接將字符串嵌入到WHERE子句中就可以了。 易於注入的代碼的示例是:
Model.where("name LIKE '#{params[:name]}'")
雖然選擇的答案會起作用,但我注意到如果你試圖輸入一個搜索“Raul Riera”就會中斷,因為它會在兩種情況下都失敗,因為Raul Riera不是我的名字或我的姓氏..是我的第一個姓氏......我這樣解決了
Model.where("lower(first_name || ' ' || last_name) LIKE ?", "%#{search.downcase}%")
使用Arel,您可以避免使用以下內容手動編寫SQL:
Model.where(
%i(name first_name last_name)
.map { |field| Model.arel_table[field].matches("%#{query}%")}
.inject(:or)
)
如果要匹配的字段列表是動態的,這將特別有用。
最好的方法是:
Model.where("attr_a ILIKE :query OR attr_b ILIKE :query", query: "%#{query}%")
在模型的所有領域中搜索的更通用的解決方案將是這樣的
def search_in_all_fields model, text
model.where(
model.column_names
.map {|field| "#{field} like '%#{text}%'" }
.join(" or ")
)
end
或者更好地作為模型本身的范圍
class Model < ActiveRecord::Base
scope :search_in_all_fields, ->(text){
where(
column_names
.map {|field| "#{field} like '%#{text}%'" }
.join(" or ")
)
}
end
你只需要像這樣調用它
Model.search_in_all_fields "test"
在你開始..之前,沒有,sql注入可能不會在這里工作,但仍然更好,更短
class Model < ActiveRecord::Base
scope :search_all_fields, ->(text){
where("#{column_names.join(' || ')} like ?", "%#{text}%")
}
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.