2011-01-23 91 views
4

我在非用戶模型的視圖中寫了一個表單,允許訪問者登錄。我想先檢查一下這是否正常。所以我讓行動「索引」進行測試。導軌路由到錯誤的URL

<%form_tag(:controller=>"users",:action=>"index") do %> 
    Name: <%=text_field_tag "name" %><br>  
    Password: <%=password_field_tag "password" %><br> 
    <%=submit_tag "Login" %> 
<% end -%> 

出人意料的是,軌道路徑引導頁的「新」的觀點,而瀏覽器的導航欄仍顯示:

http://0.0.0.0:3000/users 

當我刷新頁面,它會顯示正常的「索引」頁面。

這是怎麼發生的?

更令人毛骨悚然的是,當我將上述代碼中的:action更改爲:action=>"new"時,屏幕顯示「路由錯誤」。當我刷新它時,它會呈現正常的「新」視圖。

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 
+0

控制器的代碼是什麼?問題在於此。 – 2011-01-23 14:00:21

+0

rails 3佈線對我來說好像是一條意大利麪~~ – lkahtz 2011-01-23 14:13:05

+0

這是一個rails3的bug嗎? – lkahtz 2011-01-23 14:43:30

回答

5

Apneadiving的答案是正確的,但是我想澄清一些事情是很重要的:

什麼頁面,你試圖讓用戶?聽起來你想讓用戶進入索引頁面(你很驚訝用戶登陸新頁面)。

第一個:您應該瞭解您所做的HTTP請求類型與控制器指向瀏覽器的位置之間的關係。請參閱http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions

基本上,您的表單正在向POST請求提交/users網址。控制器始終將POSTS路由到這個地址以執行CREATE操作。因此,Apneadiving解釋,你發送的post數據都沒有創造期待的那些,所以保存失敗和您重定向到users/new

現在,我看到,在您的形式指定::controller => 'users', :action => 'index'。所以,這是我看到它看起來像你希望人們登陸索引頁面的地方。然而,你需要理解的是,Rails表單助手並不神奇地與控制器層相連。

第二個:知道信息流在Rails中基本上是單向的:模型中的東西可以發送到控制器,而不是其他方式。控制器的東西可以轉到視圖,但不是其他方式。

控制器可以從用戶那裏接收的唯一東西就是HTTP請求。當您使用表單標籤助手時,您只需使用快捷方式定義HTML元素的actionmethod屬性。請參閱http://www.w3.org/TR/html401/interact/forms.html#h-17.13

因此,即使您指定了:action => 'index',表單仍在發送POST請求(默認情況下爲表單POST)。控制器不知道您是否意圖針對該人的索引操作請求,它只知道它在/users網址上收到POST,而不是GET。因此它將該請求路由到CREATE操作。

這就是REST的全部內容。

解決辦法:

您需要使用尚未預定義的動作。在你的路由,它看起來像你試圖做到這一點,當你把:

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

此代碼將正確地接受POST請求users/123/login

但是,因爲您在用戶的集合的成員(而不是集合本身)上指定了此屬性,您將不得不提供特定的USER_ID以便正確處理該請求。因爲您使用此操作進行登錄,所以這不是您需要的。見http://guides.rubyonrails.org/routing.html#nested-resources

你需要做的,而不是什麼是指定收集這條路線(即:users/login):

resources :users do 
    collection do 
    post 'login' 
    end 
end 

然後,在你的形式,改變你的表單標籤說:controller => 'users', :action => 'login'

最後,在您的控制器中,您需要指定登錄操作。在這種情況下,它可以是簡單的:

def login 
    redirect_to users_path 
end 

所有這一切需要做的是接受POST和重定向到索引。但是,如果您希望表單中的參數粘住,則需要在LOGIN操作中處理它們。重定向後,它們不會持續存在,並可用於INDEX操作。

我希望這能爲你解決問題。祝你好運!

2

你的問題就出在你的routes.rb。看看here。這個例子很清楚:

resources :photos do 
    member do 
    get 'preview' 
    end 
end 

描述:「這將識別/照片/ 1 /預覽與GET」。

因此,回到您的代碼:post login行不會導致您打算。

取而代之的是發送請求被定向到'創建'視圖,因爲這是通過輸入resources :users(請參閱here)問的問題。 因爲它不是正確保存它重定向到「新」的觀點,東陽的:

else 
    format.html { render :action => "new" } 

那麼什麼解決辦法嗎?下面是一些軌道:

  • 檢查你的日誌,他們應該是資源調試
  • 使用軌道小號--debugger把斷點和檢查變量
  • 檢查您的參數,可以我不明白爲什麼你依靠params[:project]來創建你的新用戶。