【问题标题】:Rails - How to not evaluate a field in a Ransack search formRails - 如何不评估 Ransack 搜索表单中的字段
【发布时间】:2023-04-02 17:08:02
【问题描述】:

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

在我的表单中,我有一个“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 %>

【问题讨论】:

    标签: search ruby-on-rails-3.1 meta-search


    【解决方案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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        我想实现类似的东西,即替换 客户通过 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的相关部分( span4span8btn btn-large btn-primary 标记由提供 Twitter's 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_anythingcustomer_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 已加载。)

        【讨论】:

          猜你喜欢
          • 2013-03-02
          • 1970-01-01
          • 2015-01-24
          • 2014-10-14
          • 2012-10-29
          • 1970-01-01
          • 1970-01-01
          • 2012-07-19
          • 1970-01-01
          相关资源
          最近更新 更多