我正在使用Rails 3.2.2和MySQL。我按用户名(例如,John
,Anthony
,Mark
)搜索数据库表列:
# User controller
User.search_by_name(params[:search]).order(:name)
# User model
def self.search_by_name(search)
if search
where('users.name LIKE ?', "%#{search}%")
else
scoped
end
end
但是,由于名称可以由两个或更多字符串组成(例如,John Henry
或Henry John
,Anthony Maria
或Maria Anthony
,Mark Alfred
或Alfred Mark
),我想在params[:search]
提供多个名称时搜索用户。我试着用
def self.search_by_name(search)
if search
search.split(' ').each do |string|
where('users.name LIKE ?', "%#{string}%")
end
else
scoped
end
end
但是我收到以下错误(例如,鉴于我正在搜索John Henry
):
NoMethodError (undefined method `order' for ["John", "Henry"]:Array).
如何正确搜索多个名称?
答案 0 :(得分:1)
我完全认为你应该做以下其中一项,
http://devzone.zend.com/26/using-mysql-full-text-searching/
http://www.ibm.com/developerworks/library/os-php-sphinxsearch/
答案 1 :(得分:1)
使用squeel gem。
def self.search_by_name(search)
if search
where(name.like_any search.split)
else
scoped
end
end
请注意,这不会通过匹配级别来排序。为此你需要一个搜索引擎实现,比如sphinx,solr,xapian的宝石
另请注意,由于您的意图是“或”条件,因此您对每种方法的原始用法都是无用的。如果你不介意发出与搜索词一样多的数据库查询,你甚至可以伪造匹配级别的顺序。
def self.search_by_name(search)
if search
results = search.split.map do |string|
where('users.name LIKE ?', "%#{string}%").all
end.flatten
ids = results.map(&:id)
# desc order by count of matches
ordered_results = results.uniq.order { |result| -ids.count(result.id) }
else
scoped.all
end
end
这不是一个可以进一步限定的Arel关系,而是一个普通的数组。 注意'all'调用,所以甚至不要在大数据库上尝试这个。 另请注意,如果搜索为'a b',则不会在'b a'上方命令'a b'。 所以我有点玩得开心。