我在使用postgres作为数据库的rails 3.2应用程序中使用ransack进行搜索。
我有一个发票模型,每张发票都属于买家。下面是索引页面中的搜索表单。
视图/发票/ index.html.erb
<%= search_form_for @search do |f| %>
<%= f.text_field :buyer_name_cont %>
<%= f.submit "Search"%>
<% end %>
这是我的控制器代码。
控制器/ invoices_controller.rb
def index
@search = Invoice.search(params[:q])
@invoices=@search.result(:distinct => true).paginate(:page => params[:page], :per_page => GlobalConstants::PER_PAGE )
respond_to do |format|
format.html # index.html.erb
format.json { render json: @invoices }
end
end
假设买方的发票上有“蝙蝠侠”的名字。
如果我搜索“蝙蝠”,我会在结果中收到发票。 如果我搜索“Man”,我会再次收到结果中的发票。 但如果我搜索“蝙蝠侠”,我就不会在结果中收到发票。
我知道这可能是微不足道的,但我无法解决。
更新
当我尝试使用pgAdmin在数据库中直接形成sql查询时,我意识到在数据库中买方名称中有多个空格,类似于“Bat.space.space.space.Man”。
可以做些什么来让“Bat.space.Man”搜索在结果中找到“Bat.space.space.space.Man”吗?
答案 0 :(得分:0)
您可以清理数据。例如regexp_replace()
。在数据库中运行一次:
UPDATE invoice
SET buyer = regexp_replace(buyer, '\s\s+', ' ', 'g')
WHERE buyer <> regexp_replace(buyer, '\s\s+', ' ', 'g');
并消毒新的插件&amp;同样更新。
\s
..“白色空间”的简写(包括制表符或奇怪的空格)
第4个参数'g'
用于“全局”,需要替换所有实例,而不仅仅是第一个。
答案 1 :(得分:0)
Ransack不支持续订多项,我解决了我的定制方式的要求。细节如下:
为您的模型添加范围:
scope :like_search, ->(column, value) {
keywords = value.to_s.split.map{ |k| "%#{k}%" }
where(Array.new(keywords.size, "#{column} ILIKE ?").join(' AND '), *keywords)
}
在你看来。而不是使用ransack提供的f.text_field :buyer_name_cont
,而是使用普通字段助手text_field_tag :buyer_name, params[:buyer_name]
然后限制你的搜索范围:
scope = Invoice.like_search(:name , params[:buyer_name])
@q = scope.ransack(params[:q])