开发者

edit form routing - on update submit runs #show method instead of #update

开发者 https://www.devze.com 2023-02-02 12:35 出处:网络
I have an app with vanity urls and I\'ve been struggling with allowing the user to update attributes. The edit form is loading correctly, but after the form is submitted, instead of running the update

I have an app with vanity urls and I've been struggling with allowing the user to update attributes. The edit form is loading correctly, but after the form is submitted, instead of running the update method, rails reroutes to root. Not exactly sure why this is happening....

# users_controller
  def edit 
    @user = User.find(params[:id]) 
  end

  def to_param  # overridden
     username.parameterize
  end

  def update 
      @user = User.find(params[:id]) 
      if @user.update_attributes(params[:user]) 
         redirect_to user_url(current_user.username), :flash => { :success => "success" }
      else
        redirect_to user_url(current_user.username), :error => { :error => "shit" }
      end
   end

routes

resources :users do
     resources :friends
   end

  match '/:username' => 'users#show', :as => "user"

form

<%= form_for @user do |form| %>  
<%= render 'shared/error_messages', :object => form.object %>
 <div class="form">  
    <p> <%= form.label :description, "Message to friends" %>  <br />  
     <%= form.text_area :description %> </p> 

     <%= form.submit %>  
 </div>  
 <% end %>

dev log

Started GET "/users/1/edit" for 127.0.0.1 at Wed Jan 05 19:07:28 -0500 2011
  Processing by UsersController#edit as HTML
  Parameters: {"id"=>"1"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
Rendered shared/_error_messages.html.erb (0.6ms)
ApplicationController::current_user
ApplicationController::current_user_session
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
ApplicationController::current_user_session
ApplicationController::current_user
ApplicationController::current_user
Rendered users/edit.html.erb within layouts/application (27.6ms)
Completed 200 OK in 53ms (Views: 38.7ms | ActiveRecord: 0.3ms)


    Started POST "/1" for 127.0.0.1 at Wed Jan 05 19:08:06 -0500 2011
    开发者_开发技巧  Processing by UsersController#show as HTML
      Parameters: {"commit"=>"Update User", "authenticity_token"=>"OM1lIzizuFCYlxC3XmtmG/btqAsyjekHtqsiwlUDn3M=", "utf8"=>"✓", "username"=>"1", "user"=>{"description"=>"Hello people! Give me your address. Get a postcard."}}
      User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."username" = '1') LIMIT 1
    Redirected to http://0.0.0.0:3000/
    ApplicationController::current_user
    ApplicationController::current_user_session
      User Load (0.3ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
      CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
    ApplicationController::current_user_session
    Completed 302 Found in 102ms

relevant rake routes:

 users GET    /users(.:format)                             {:controller=>"users", :action=>"index"}
                                 POST   /users(.:format)                             {:controller=>"users", :action=>"create"}
                        new_user GET    /users/new(.:format)                         {:controller=>"users", :action=>"new"}
                       edit_user GET    /users/:id/edit(.:format)                    {:controller=>"users", :action=>"edit"}
                            user GET    /users/:id(.:format)                         {:controller=>"users", :action=>"show"}
                                 PUT    /users/:id(.:format)                         {:controller=>"users", :action=>"update"}
                                 DELETE /users/:id(.:format)                         {:controller=>"users", :action=>"destroy"}


@Beerlington. Your answer was very close and led me finding a fix. Defining the method didn't do it but what did was defining the action.

<%= form_for @user, :url => { :action => "update" } do |form| %> 

That did the trick for some reason... Not sure why the action wasn't defined as update.


Look at the generated HTML for your form. I'm betting the action looks something like

action="/1"

So when the form is submitted, your route file says

match '/:username' => 'users#show', :as => "user"

and that is where you are sent

Started POST "/1" for 127.0.0.1 at Wed Jan 05 19:08:06 -0500 2011
  Processing by UsersController#show as HTML

I think form_for relies on to_param to generate the action for the form. Since you over wrote it, you're getting unintended behavior.


Your code looks fine to me, but the log is showing that the form is not rendering the hidden _method field containing "put". This could be caused by the form_for helper not recognizing @user as an existing record. I have no idea why this might be happening, but a temporary fix would be to add the following to your form_for helper:

:html => { :method => :put}
0

精彩评论

暂无评论...
验证码 换一张
取 消