2014-01-26 46 views
0

我有一個頁面一個Rails應用程序供用戶編輯自己的個人資料的Rails沒有得到路由匹配[PUT] 「/ manage_users」

app/views/manage_users/edit.html.erbapp/views/manage_users/new.html.erb包含:

<%= render 'form' %> 

app/views/manage_users/_formt.html.erb包含:

<%= form_for(@user, :as => :user, :url => {:action => @form_action, :id => @user.id}) do |f| %> 

當我火了http://localhost:3000/manage_users/2/edit的頁面它顯示了我一個典型的表單編輯用戶對象的數據。如果我空出的電子郵件地址http://snag.gy/atnmV.jpg並提交表單,我得到我期望http://snag.gy/NRfwn.jpg一個錯誤,現在的網址是http://localhost:3000/manage_users/2

Started PUT "/manage_users/2" for 127.0.0.1 at 2014-01-25 21:01:45 -0600 
Processing by ManageUsersController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"B44/1b5m8usyAfe0hzLHNyjk/7Fpn5iEu3u6wGJMGL0=", "user"=>{"user_details_attributes"=>{"first_name"=>"Jeff", "last_name"=>"Smith", "id"=>"2"}, "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "button"=>"", "id"=>"2"} 

如果我把電子郵件地址回並提交表單時, url現在指向http://localhost:3000/manage_users?id=2,我得到錯誤No route matches [PUT] "/manage_users"

爲什麼它這樣做,我該如何解決它。如果我只是進入初始頁面來編輯用戶並立即保存(而不是刪除電子郵件),則一切正常。

應用程序/控制器/ manage_users_controller.rb

class ManageUsersController < ApplicationController 

    before_filter :admin_only, :except => [:edit, :update] 

    # GET /manage_users 
    # GET /manage_users.json 
    def index 
    @users = User.active 

    respond_to do |format| 
     format.html # index.html.erb 
     format.json { render json: @users } 
    end 
    end 

    # GET /manage_users/new 
    # GET /manage_users/new.json 
    def new 
    @user = User.new 
    @user.build_user_details 
    @form_action = 'create' 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @user } 
    end 
    end 

    # GET /manage_users/1/edit 
    def edit 
    @user = User.find(params[:id]) 
    @permissions_disabled = params[:id].to_i == current_user.id.to_i 
    #p @permissions_disabled 
    able_to_edit_profile? 

    session[:return_to] ||= request.referer 

    @form_action = 'update' 
    end 

    # POST /manage_users 
    # POST /manage_users.json 
    def create 
    @user = User.new(params[:user]) 

    #p "in create" 
    respond_to do |format| 
     if @user.save 
     format.html { 
      flash[:notice] = 'User was successfully created.' 
      redirect_to(:action => :index) 
     } 
     format.json { render json: @user, status: :created, location: @user } 
     else 
     format.html { render action: "new", notice: 'Error creating user.' } 
     format.json { render json: @user, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PUT /manage_users/1 
    def update 
    @user = User.find(params[:id]) 
    able_to_edit_profile? 

    # required for settings form to submit when password is left blank 
    if params[:user][:password].blank? 
     params[:user].delete("password") 
     params[:user].delete("password_confirmation") 
    end 

    respond_to do |format| 
     if @user.update_attributes(params[:user]) 
     @user.save  

     # sign the user in with their new password so it doesn't redirect to the login screen 
     if current_user == @user 
      sign_in @user, :bypass => true 
     end 

     format.html { 
     p "in success format.html" 
      flash[:notice] = 'User was successfully updated.' 
      redirect_to session.delete(:return_to) 
     } 
     else 
     p "in else" 
     format.html { render action: "edit", notice: 'Error updating user.' } 
     #format.html { 

      #flash[:notice] = @user.errors 
     # redirect_to edit_manage_user_path(@user) 
     #} 
     end 
    end 
    end 

    private 

    # If the user is not an admin and trying to edit someone else's profile, redirect them 
    def able_to_edit_profile? 
    if !current_user.try(:admin?) && current_user.id != @user.id 
     flash[:alert] = "That area is for administrators only." 
     redirect_to :root 
    end 
    end 
end 

EDIT

所以通過改變這樣的:

format.html { render action: "edit", notice: 'Error updating user.' } 

到:

format.html {    
    flash[:notice] = @user.errors.full_messages.to_sentence 
    redirect_to edit_manage_user_path(@user) 
} 

我可以繞過這個問題。我仍然好奇爲什麼渲染'編輯'在失敗的更新後不起作用。

+0

窗體是什麼樣子的? – jcm

+0

自從我發佈'form_for'這一行後,表單就無關緊要了。問題已經很長了,所以我不想發佈任何不必要的東西。 – Catfish

回答

0

從update方法(在失敗路徑中)呈現編輯操作時,它不會運行編輯方法,因此在呈現表單時@form_action爲零。你需要解決這個問題。

我通常不需要設置網址,只有在極少數情況下才可以。您可以將它保留,讓rails負責網址和HTTP方法。

+0

只是爲了更詳細地解釋這一點:當'@form_action'爲零時,url只包含id參數,意思是它的「/ manage_users?id = x」。由於存在@user(不是User.new實例,在這種情況下,它會顯示您想要創建用戶),因此rails會猜測您想更新'@user',因此該方法爲PUT。如果你redirect_to而不是渲染來編輯,它應該可以正常工作。 – Ninigi

+0

@Chai重定向的問題是,如何將對象錯誤設置爲Flash變量?此外,我想我仍然不明白爲什麼redirect_to會工作,但渲染'編輯'不會。你能否詳細說明一下?我想我不明白爲什麼如果你點擊url'localhost:3000/manage_users/2/edit',它工作得很好,但是如果你從失敗的更新中渲染'編輯',那是行不通的。 – Catfish

+0

您可能會將'render edit'(呈現視圖)與'edit'(調用方法)混淆。通常,更新方法將在錯誤上進行編輯,而不是重定向。即 - 你會留在'顯示'網址(/ manage_users/2)。如果你想在編輯視圖中訪問實例變量,你需要實例化它們。您可以在更新方法中執行此操作。 – Swards

相關問題