Я хотел добиться чего-то подобного, то есть заменить пробелы в пользовательском вводе подстановочным знаком SQL %
, чтобы поле поиска «Foo Bar» соответствовало «Foo Bar», но также и «Foomster Q. Bar».и "Foo Glolubar".Я также хотел добавить подстановочный знак в начало и конец фактического параметра поиска, чтобы "Fiefoo Newton Barrister" также совпадал.
Вот как.Соответствующие части app/controllers/customers_controller.rb
:
class CustomersController < ApplicationController
# GET /customers
# GET /customers.json
def index
@search = Customer.search(params[:q])
@customers = @search.result
...
respond_to do |format|
format.html # index.html.erb
format.json { render json: @customers }
end
end
...
end
Соответствующие части представления app/views/customers/index.html.erb
(разметка span4
, span8
и btn btn-large btn-primary
обеспечивается Twitter Bootstrap framework ):
<% require 'action_view' %>
<div class="row">
...
<div class="span4"> <!-- The search criteria -->
...
<%= search_form_for @search do |f| %> <!-- this is a Ransack-provided form -->
<div class="field">
<%= f.label :customer_name_whitespaces_match_anything, "Name is or contains:" %>
<%= f.text_field :customer_name_whitespaces_match_anything, class: "my-textbox" %>
...
<%= f.label :customer_address_whitespaces_match_anything, "Address is or contains:" %>
<%= f.text_field :customer_address_whitespaces_match_anything, class: "my-textbox" %>
...
</div>
<br/>
<div class="actions">
<%= f.submit "Search", class: "btn btn-large btn-primary" %>
</div>
<% end %>
</div>
<div class="span8"> <!-- The search results -->
...
<table border="1" cellpadding="5">
<tr>
<th><%= sort_link(@search, :customer_name, "Customer name") %></th>
...
<th><%= sort_link(@search, :customer_address, "Address") %></th>
...
</tr>
<% @customers.each do |c| %>
<tr>
<td><%= link_to c.customer_name, customer_path(c, search: @search) %></td>
...
<td><%= c.customer_address %></td>
...
</tr>
<% end %>
</table>
</div>
...
</div>
Вы заметите предикаты поиска customer_name_whitespaces_match_anything
и customer_address_whitespaces_match_anything
.Они относятся к пользовательскому предикату поиска, который я определил в файле config/initializers/ransack.rb
.Его содержимое:
Ransack.configure do |config|
config.add_predicate 'whitespaces_match_anything',
:arel_predicate => 'matches', # so we can use the SQL wildcard "%"
# Format the incoming value: replace spaces by the SQL wildcard "%".
:formatter => proc {|v| "%"+v.gsub(" ","%")+"%"}
end
Теперь поисковый термин манипулируется пользовательским предикатом, прежде чем он передается в запрос SQL, но после поиска в полях ввода поисковой формы по-прежнему отображается искомое условие, введенное пользователем изначально.
(В результатах поиска у меня есть ссылка от имени клиента на отдельного клиента, что приведет к загрузке представления app/views/customers/show.html.erb
.)