Ruby on rails Rails路由到错误的URL

Ruby on rails Rails路由到错误的URL,ruby-on-rails,Ruby On Rails,我在非用户模型的视图中编写了一个表单,允许访问者登录。我想先看看这是否有效。所以我做了一个动作“索引”来进行测试 <%form_tag(:controller=>"users",:action=>"index") do %> Name: <%=text_field_tag "name" %><br> Password: <%=password_field_tag "password" %><br> &

我在非用户模型的视图中编写了一个表单,允许访问者登录。我想先看看这是否有效。所以我做了一个动作“索引”来进行测试

<%form_tag(:controller=>"users",:action=>"index")  do %>
  Name: <%=text_field_tag "name"  %><br>    
  Password: <%=password_field_tag "password" %><br>
  <%=submit_tag "Login"  %>
<% end -%>
当我刷新页面时,它会显示正常的“索引”页面

为什么会这样

更奇怪的是,当我将上面代码中的
:action
更改为
:action=>“new”
时,屏幕显示“路由错误”。当我刷新它时,它会显示正常的“新建”视图

users\u 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
Testdrive::Application.routes.draw do

  resources :users do
    member do
      post 'login'
    end
  end
  resources :cars 

您的问题在于routes.rb。看一看。这个例子非常清楚:

resources :photos do
  member do
    get 'preview'
  end
end
描述:“这将识别/photos/1/使用GET预览”

因此,回到您的代码:
post login
行不会指向您想要的位置

相反,post请求被定向到“创建”视图,因为这是您通过键入
resources:users
所要求的(请参阅)。 由于未正确保存,它会重定向到“新建”视图,原因如下:

else
  format.html { render :action => "new" }
那么什么解决方案呢?以下是一些曲目:

  • 检查日志,它们应该是要调试的资源
  • 使用rails s--调试器设置断点并检查变量
  • 检查您的参数,我不明白您为什么依赖
    params[:project]
    来创建新用户

A领导的回答是正确的,但我认为澄清一些事情很重要:

您试图让用户访问哪个页面?听起来您希望用户进入索引页面(用户登录到新页面时,您会感到惊讶)

首先:您应该了解您发出的HTTP请求类型与控制器将浏览器指向的位置之间的关系。看

基本上,您的表单是向
/users
url提交POST请求。控制器始终将发往此地址的邮件路由到您的创建操作。因此,正如Apreading所解释的,您发送的post参数不是所期望的,因此保存失败,您被重定向到
users/new

现在,我看到您在表单中指定了:
:controller=>'users',:action=>'index'
。这就是我看到的,看起来你希望人们在索引页面上登陆。但是,您需要了解的是,Rails表单帮助程序并没有神奇地链接到控制器层

Second:知道Rails中的信息流基本上是单向的:模型中的东西可以传递给控制器,但不能以另一种方式传递。控制器中的内容可以转到视图,但不能从另一个方向转到视图

控制器可以从用户接收的唯一内容是HTTP请求。当您使用表单标记帮助程序时,您只是使用一个快捷方式来定义HTML
form
元素的
action
method
属性。看

因此,即使指定了
:action=>“index”
,表单仍在发送POST请求(默认情况下,表单POST)。控制器不知道您的意思是让该用户的请求点击索引操作,它只知道它在
/users
url处收到了一个帖子,而不是一个GET。因此,它将该请求路由到CREATE操作

这就是休息的意义所在

解决方案:

您需要使用尚未预定义的操作。在您的路线中,当您放置:

resources :users do
  member do
    post 'login'
  end
end
此代码将正确接受对
users/123/login
的POST请求

但是,由于您在用户集合的成员而不是集合本身上指定了此项,因此必须提供特定的用户ID才能正确处理该请求。因为您正在使用此操作登录,所以这不是您需要的。看

您需要做的是为集合指定此路由(即:
users/login
):

然后,在表单中,将表单标记更改为
:controller=>“users',:action=>“login”

最后,您需要在控制器中指定登录操作。在这种情况下,它可以简单到:

def login
  redirect_to users_path
end
所要做的就是接收帖子并重定向到索引。但是,如果希望表单中的参数保持不变,则需要在登录操作中处理它们。它们不会持久存在,并在重定向后可用于索引操作


我希望这能帮你把事情弄清楚。祝你好运

控制器的代码是什么?问题就在这里。rails 3路由现在对我来说似乎是个意大利面条~~这是rails 3的一个bug吗?你能把routes.rb文件也放上去吗?我已经用routes.rb更新了我的问题。请帮帮我~你太棒了!~我会根据你的回复退房。。。非常感谢~谢谢安德鲁。你太棒了~~这是非常非常彻底和有用的!!现在我更清楚地了解了rails路由的工作原理。是的,由于我对rails还不熟悉,我正在尝试使用rails3一段时间。很有趣~很高兴有你耐心的回答。我想给你两张票~不,老兄,这是你应得的;)
resources :users do
  collection do
    post 'login'
  end
end
def login
  redirect_to users_path
end