Home > front end >  Why Ransack doesn't show any search results
Why Ransack doesn't show any search results

Time:03-22

I refer to the official teaching and also read all the similar Q&A on Stackoverflow, but I am not using Pagy and AJAX, so it is not the same error.

I'm trying to search for the value of the name column on Task model. But when I enter a keyword that matches an existing name value and press Search, the result is blank. I can't figure out why?

This is part of the controller:

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

This is View

<%= 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>

This is the terminal log

Started GET "/my_task_list?q[name]=TT&commit=搜尋" 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)

CodePudding user response:

Your code should say Task.ransack(name_cont: params[:q][:name]) because your params look like this: {"q"=>{"name"=>"TT"} }.

But, you are using the same action, index to render the intial page (when the user lands on it) and also after Search is pressed. When the page renders first, i.e http://localhost/tasks, q parameter does not exist and writing params[:q][:name] will obviously fail because params[:q] is nil.

Ideally, you should keep index to render the search form and have another action for search.

But, if you want to keep everything as is you could write it as follows:

Assuming you have a TasksController:

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

And the search form is on /tasks:

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

You see I added name_cont as the search field. You could add more, i.e status_eq, and all will be sent to the server in params[:q] when you press Search.

Pay attention to the logs to see how q looks like and what query is performed in Tasks.

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

  • Related