2

我是 Rails 的初学者,在改进我的搜索查询时遇到了一些问题:

在控制器中我调用:

def index
 if params[:search]
  @persons = Person.search(params[:search]).order("created_at DESC")
 else
  @persons = Person.order("created_at DESC")
 end
end

在模型中我有:

 def self.search(query)
  where("name like ?", "%#{query}%")
 end

所以实际上我只过滤名称!现在我尝试改进它,但它没有解决我喜欢它的方式,我的目标是用户可以输入例如:

 John
 Smith
 Smith John
 John Smith

它总是应该返回John Smith。那么如何写这么长的sql查询呢?提前致谢!

4

3 回答 3

2

此搜索方法应该适合您:

def self.search(query)
  return where('FALSE') if query.blank?

  conditions = []
  search_columns = [ :vorname, :nachname ]

  query.split(' ').each do |word|
    search_columns.each do |column|
      conditions << " lower(#{column}) LIKE lower(#{sanitize("%#{word}%")}) "
    end
  end

  conditions = conditions.join('OR')    
  self.where(conditions)
end
  • 此代码是安全的:sanitizes调用 SQL 之前的字符串
  • 此代码很灵活:您可以非常轻松地添加更多列进行搜索
  • 此代码很灵活:您可以轻松地拆分空间(- / |等)
  • 此代码可用于链范围
  • 此代码不区分大小写,可与John SmithJohN SMITh

如有需要,请随时提出问题!

于 2013-11-12T16:38:05.130 回答
0

做这样的事情怎么办?

def self.search(query)
  where("name LIKE ? or forename LIKE ? or concat(name, ', ', forename) LIKE ?", "%#{query}%", "%#{query}%" , "%#{query}%")
end

如果您的搜索查询变得非常复杂,您可能需要查看搜索 gem,例如elasticsearch

于 2013-11-12T16:41:48.253 回答
0

您拥有的内容应该适用于以下搜索查询

John
Smith
John Smith

如果您希望它也适用于反向搜索查询,请执行以下操作

def self.search(query)
  name_parts = query.split(' ')
  condition = name_parts.collect{|part| "name like #{sanitize("%#{part}%")}"}.join(' AND ')
  where(condition)
 end
于 2013-11-12T16:41:48.777 回答