5

我在 Rails 3.1 中使用Ransack Gem。一切都按预期工作。但是,我有一个搜索表单,可以使用我遇到问题的 Soundex 列查找人员。

在我的表单中,我有一个“given_name_soundex_cont”字段,用户将输入名称“Joe”。我的控制器将“joe”转换为 soundex 代码,然后 Ransack 在“given_name_soundex”列中查找匹配项。

所有匹配的记录都返回并且看起来很好,除了用户输入单词“joe”的字段现在显示 soundex 值(当然因为我更改了参数)。

所以我想我可以添加一个“given_name_cont”字段并隐藏“given_name_soundex_cont”字段,但现在 Ransack 想要在查询中包含“given_name_cont”,这是我不想要的。

有谁知道我如何在 Ransack 搜索表单中包含字段而不需要 Ransack 实际评估它们。这样我可以指定哪些字段不被评估,哪些不被评估。

如果它有帮助,这就是我的控制器中的内容:

def index

  if !params[:q].blank?  # nil.blank? and [].blank? are true
    search_params = params[:q]
    search_params[:given_name_soundex_cont] = convert_to_soundex(search_params[:given_name_soundex_cont])
    @q = Person.search(search_params)
    @results = @q.result.limit(50)
  else
    @q = Person.search(params[:q])
    @results = []
  end

end


private 
    def convert_to_soundex(text)
      Text::Soundex.soundex(text.to_s)
    end

在我看来:

<%= search_form_for @q do |f| %>
  <label>Given Name:</label>
  <%= f.text_field :given_name_soundex_cont %>

  <%= f.submit %>
<% end %>
4

3 回答 3

1

创建一个格式化参数的 ransacker。我没有尝试过,但我认为它会起作用(通过https://github.com/ernie/ransack/issues/36)。

ransacker :given_name_soundex, :formatter => proc {|v| Text::Soundex.soundex(v)} do
  parent.table[:given_name_soundex]
end
于 2012-03-15T13:14:25.993 回答
0

您可以在视图中重新使用params[:q][:given_name_soundex]以覆盖传递给#ransack/的值#search

于 2012-03-14T20:47:06.493 回答
0

我想实现类似的东西,即用 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.erbspan4和标记由 Twitter 的 Bootstrap 框架提供):span8btn btn-large btn-primary

<% 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_anythingcustomer_address_whitespaces_match_anything. 这些指的是我在 file 中定义的自定义搜索谓词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被加载。)

于 2012-10-18T16:44:38.360 回答