我正在使用index
方法列出所有学生。现在我在索引中添加一个text_field_tag
的搜索。我的功能正常,但搜索值在网址中显示为查询字符串。我不想要这个。
我的观看代码:
<p>
<%= form_tag students_path, :method => 'get' do %>
Find by name: <%= text_field_tag :search %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</p>
我的控制器代码是
def index
searchString = params[:search]
if searchString
@students = Student.where("LastName like ?", "%#{searchString}%").paginate(:page => params[:page])
else
@students = Student.paginate(:page => params[:page])
end
end
我目前的网址如下所示:
http://localhost:3000/students?utf8=%E2%9C%93&search=A
我只需要/students
。请建议最佳做法
答案 0 :(得分:3)
您需要使用POST
请求而不是GET
。为了实现这一目标,请更改您的form_tag
:
<%= form_tag students_path, :method => 'get' do %>
到
<%= form_tag students_path, :method => 'post' do %>
可能出现什么问题......
正如@carlosramireziii所提到的,回答这个问题,需要更多的工作(他是绝对正确的!),所以 - 有更新
<强> 1。自定义路线
如果您要自行配置路由,则继续执行此操作的方法之一是添加路由,以便正确接受您的请求。看一下 config / routes.rb :
Rails.application.routes.draw do
match '/students', controller: :students, action: :index, via: [:get, :post]
# other definitions
end
这样的定义将为您创建以下路线:
students GET|POST /students(.:format) students#index
这会使您的新POST
请求很好地落入students#index
,从而产生预期结果。 然而,如果您通过resources
定义路线,则不是那么容易改变。这导致我们......
<强> 2。修改标准resources
路线
如果学生的路线定义如下:
Rails.application.routes.draw do
resources :students
# other definitions
end
注册了以下路线:
students GET /students(.:format) students#index
POST /students(.:format) students#create
new_student GET /students/new(.:format) students#new
edit_student GET /students/:id/edit(.:format) students#edit
student GET /students/:id(.:format) students#show
PATCH /students/:id(.:format) students#update
PUT /students/:id(.:format) students#update
DELETE /students/:id(.:format) students#destroy
这表明POST
请求属于students#create
。为了使其有效,您需要将create
操作更改为:
class StudentsController < ApplicationController
# code omitted
def create
if params.include?('search')
@students = Student.where("LastName like ?", "%#{searchString}%").paginate(:page => params[:page])
render :index
else
# your current code from create action
end
end
end
虽然这样可行但是不推荐这样做。 create
动作现在做了两件事,这被认为是一种糟糕的模式(至少是难闻的气味),并且容易出错。
那么,我们能做什么?
以search
正确的方式
<强> 1。自定义search
路线
定义自定义collection route:
Rails.application.routes.draw do
resources :students do
collection do
post :search
end
end
# other definitions
end
注册以下路线:
search_students POST /students/search(.:format) students#search
students GET /students(.:format) students#index
POST /students(.:format) students#create
new_student GET /students/new(.:format) students#new
edit_student GET /students/:id/edit(.:format) students#edit
student GET /students/:id(.:format) students#show
PATCH /students/:id(.:format) students#update
PUT /students/:id(.:format) students#update
DELETE /students/:id(.:format) students#destroy
您需要更改form_tag
,如下所示:
<%= form_tag search_students_path, :method => 'post' do %>
并将search
操作添加到StudentsController
:
class StudentsController < ApplicationController
# code omitted
def search
@students = Student.where("LastName like ?", "%#{searchString}%").paginate(:page => params[:page])
# If you don't want to create separate template for `search`,
# you can try to reuse your `index` template with
# render :index
end
end
<强> 2。将students#index
与在网址
这种方法更多是REST-y,它可以将整个URL传递给其他人,因此另一个人能够看到完全相同的过滤结果,这对params
来说是不可能的。隐藏在POST
请求中。
我希望我已经涵盖了所有可能性。如果您有任何问题 - 我非常乐意回答!
祝你好运!