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