我只是将搜索添加到我的项目中,以便能够按名称查找人员。但是在我的数据库中,我有first_name
和last_name
,但是如果有人搜索全名,例如 Joe Doe 则没有结果匹配
#model
class Person < ActiveRecord::Base
def full_name
(self.first_name + ' ' + self.last_name).titleize
end
end
#controller
class PeoplesController < ApplicationController
expose(:peoples){
if params[:search]
People.where(
"first_name ILIKE ?
OR last_name ILIKE ?
", params[:search], params[:search]
)
else
People.all
end
}
end
如果有人搜索first_name,它会返回结果,last_name会返回结果,但不是全名
如果我尝试将full_name
添加到查询中,则列“full_name”不存在
感谢您的帮助
答案 0 :(得分:0)
如果有人搜索first_name,它会返回结果,last_name会返回结果,但不是全名
这是预期的,因为没有一个字段包含整个名称,只包含部分,因此它们永远不会匹配。一个简单的方法就是用空格分割seatch术语,检查你是否有两个或更多的项目。
# app/queries/people_search_query.rb
class PeopleSearchQuery
attr_reader :relation
def initialize(relation = Person.all)
@relation = relation
end
def search(params)
if params[:search]
where_str = "first_name ILIKE ? OR last_name ILIKE ?"
split = params[:search].split(" ", 2)
if split.size > 1
relation.where(where_str, *split)
else
relation.where(where_str, *(split * 2))
end
else
relation
end
end
end
class PeoplesController < ApplicationController
expose(:peoples) { PeopleSearchQuery.new.search(params) }
end
答案 1 :(得分:0)
虚拟字段不在数据库级别。如果不解释该虚拟字段对数据库的影响,则无法进行基于数据库的搜索。
您的字段的定义基本上是由它组成的列的列表。由于您使用的是PostgreSQL,因此可以使用using pg_search
的全文搜索功能。它能够一次搜索多个列。
事实上,在文档中有一个如何做到几乎完全符合你的情况的例子。我只是在这里复制粘贴它。 Go figure.
# Model
class Person < ActiveRecord::Base
include PgSearch
pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
end
# Example code for the Rails console
person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
Person.search_by_full_name("Grant") # => [person_1, person_2]
Person.search_by_full_name("Grant Hill") # => [person_1]
这件事值得额外依赖,取决于你。如果您发现自己处于构建许多复杂搜索的情况,这可能有所帮助。