为什么 Ransack 不显示任何搜索结果

Why Ransack doesn't show any search results

我参考了官方的教学,在Whosebug上也看了所有类似的Q&A,但是我没有使用Pagy和AJAX,所以不是同一个错误

我正在尝试搜索 Task 模型上 name 列的值。但是,当我输入与现有名称值匹配的关键字并按 Search 时,结果为空白。我不明白为什么?

这是控制器的一部分:

  def index
    @name = Task.ransack(name_cont: params[:q])
    @tasks = @name.result
    puts @tasks
  end

这是视图

<%= search_form_for @name do |f| %>
  <%= f.label :name, "Search for" %>
  <%= f.search_field :name, placeholder: "Mission Name" %>
  <%= f.submit %>
<% end %>

<h1><%= t('task_list') %></h1>
  <ul>
    <% @tasks.each do |task| %>
      <li>
        <%= task.name %>
        <%= t('task_status') %>:<%= task.status %>
          <%= link_to t('task_cont') , task_path(task) %>
            <%= link_to t('task_do_edit') , edit_task_path(task) %>
            <%= link_to t('task_do_kill') , task_path(task), method: :delete, data:{ confirm: t('task_do_sure') } %>
      </li>
    <% end %>
  </ul>

这是终端日志

Started GET "/my_task_list?q%5Bname%5D=TT&commit=%E6%90%9C%E5%B0%8B" for 127.0.0.1 at 2022-03-18 15:22:49 +0800
Processing by TasksController#index as HTML
  Parameters: {"q"=>{"name"=>"TT"}, "commit"=>"搜尋"}
  Task Load (0.3ms)  SELECT "tasks".* FROM "tasks" WHERE "tasks"."name" ILIKE '%{"name"=>"TT"}%'
  ↳ app/controllers/tasks_controller.rb:14:in `puts'
  Rendering layout layouts/application.html.erb
  Rendering tasks/index.html.erb within layouts/application
  Rendered tasks/_navbar.html.erb (Duration: 0.4ms | Allocations: 298)
  Rendered tasks/index.html.erb within layouts/application (Duration: 1.2ms | Allocations: 830)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered layout layouts/application.html.erb (Duration: 83.5ms | Allocations: 3871)
Completed 200 OK in 87ms (Views: 84.3ms | ActiveRecord: 0.3ms | Allocations: 5108)

你的代码应该是 Task.ransack(name_cont: params[:q][:name]) 因为你的参数看起来像这样:{"q"=>{"name"=>"TT"} }.

但是,您正在使用相同的操作,index 来呈现初始页面(当用户登陆时)以及在按下 Search 之后。当页面先渲染时,即 http://localhost/tasksq 参数不存在,写 params[:q][:name] 显然会失败,因为 params[:q]nil.

理想情况下,您应该保留 index 以呈现搜索表单并为 search 执行另一个操作。

但是,如果你想保持一切不变,你可以这样写:

假设你有一个 TasksController:

class TasksController < ApplicationController
  def index
    @query = Task.ransack(params[:q])
    @tasks = @query.result
  end
end

并且搜索表单位于 /tasks:

<%= search_form_for @query do |f| %>
  <%= f.label :name, "Search for" %>
  <%= f.search_field :name_cont, placeholder: "Mission Name" %>
  <%= f.select :status_eq, Task.statuses.map { |key, value| [key.titleize, value] }, prompt: 'Choose Status' %>
  <%= f.submit %>
<% end %>
....

你看我添加了 name_cont 作为搜索字段。您可以添加更多,即 status_eq,当您按 Search.

时,所有内容都将在 params[:q] 中发送到服务器

注意日志以查看 q 的外观以及 Tasks 中执行的查询。

Task Load (0.9ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."name" ILIKE '%test%'