我在非用户模型的 View 中编写了一个表单,允许访问者登录。我想先看看这是否有效。所以我做 Action “索引”来进行测试。
<%form_tag(:controller=>"users",:action=>"index") do %>
Name: <%=text_field_tag "name" %><br>
Password: <%=password_field_tag "password" %><br>
<%=submit_tag "Login" %>
<% end -%>
令人惊讶的是,rails 路由将页面定向到"new" View ,而浏览器导航栏仍然显示:
http://0.0.0.0:3000/users
当我刷新页面时,它显示正常的“索引”页面。
为什么会这样?
更诡异的是,当我换了
:action
在上面的代码中 :action=>"new"
,屏幕显示“路由错误”。当我刷新它时,它会显示正常的"new" View 。users_controller.rb
如下:class UsersController < ApplicationController
def index
@users=User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users }
end
end
def show
@user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @user }
end
end
def login
flash[:notice]="Hello";
end
def new
end
def create
@user = User.new(params[:project])
respond_to do |format|
if @user.save
format.html { redirect_to(@user, :notice => 'user was successfully created.') }
format.xml { render :xml => @user, :status => :created, :location => @user }
else
format.html { render :action => "new" }
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
end
end
end
end
我的 routes.rb 如下:
Testdrive::Application.routes.draw do
resources :users do
member do
post 'login'
end
end
resources :cars
最佳答案
Apneadiving 的回答是正确的,但我认为澄清一些事情很重要:
你想让用户访问哪个页面?听起来您希望用户进入索引页面(您对用户登陆新页面感到惊讶)。
第一:您应该了解您发出的 HTTP 请求类型与 Controller 将浏览器定向到的位置之间的关系。见 http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
基本上,您的表单正在向 /users
提交 POST 请求。网址。 Controller 总是将 POSTS 路由到这个地址到你的 CREATE 操作。因此,正如 Apneadiving 所解释的,您发送的 post 参数不是 CREATE 期望的参数,因此保存失败并且您被重定向到 users/new
现在,我看到您在表单中指定了::controller => 'users', :action => 'index'
.所以,这就是我认为您希望人们登陆索引页面的地方。然而,您需要了解的是,Rails 表单助手并没有神奇地链接到 Controller 层。
第二:知道信息流在 Rails 中基本上是单向的:来自模型的东西可以到达 Controller ,但不能以其他方式。来自 Controller 的事物可以进入 View ,但不能以其他方式。
Controller 可以从用户接收的唯一内容是 HTTP 请求。当您使用表单标签助手时,您只是使用了定义 action
的快捷方式。和 method
HTML 的属性 form
元素。见 http://www.w3.org/TR/html401/interact/forms.html#h-17.13
因此,即使您指定了 :action => 'index'
,您的表单仍在发送 POST 请求(表单默认为 POST)。 Controller 不知道您的意思是让该人的请求点击索引操作,它只知道它在 /users
处收到了 POST,而不是 GET。网址。因此,它将请求路由到 CREATE 操作。
这就是 REST 的全部意义所在。
解决办法:
您需要使用尚未预定义的操作。在您的 route ,当您放置以下内容时,您似乎试图这样做:
resources :users do
member do
post 'login'
end
end
此代码将正确接受对
users/123/login
的 POST 请求.但是,因为您在用户集合的 MEMBER 而非 COLLECTION 本身上指定了它,所以您必须提供特定的 USER_ID 才能正确处理该请求。因为您正在使用此操作登录,所以这不是您所需要的。见 http://guides.rubyonrails.org/routing.html#nested-resources
您需要做的是为 COLLECTION 指定此路由(即:
users/login
):resources :users do
collection do
post 'login'
end
end
然后,在您的表单中,将表单标签更改为
:controller => 'users', :action => 'login'
.最后,在您的 Controller 中,您需要指定一个登录操作。在这种情况下,它可以很简单:
def login
redirect_to users_path
end
所有要做的就是接收 POST 并重定向到索引。但是,如果您希望表单中的参数保持不变,则需要在 LOGIN 操作中处理它们。它们不会持久存在并且在重定向后可用于您的 INDEX 操作。
我希望这可以为您解决问题。祝你好运!
关于ruby-on-rails - Rails 路由到错误的 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4774184/