Switching locale after an invalid POST
I'm puzzling on the following problem: in my web app users can select their language from a dropdown box. Upon selection, a piece of Javascript takes the current url, replaces the old locale substring in it with the new locale string and sets the window.location
to the new url. That works great as long as the URL the result of a GET request.
My pr开发者_如何学编程oblem occurs when the user posts a form and it returns a validation error. The url is now a POST url, that (in my case) does not work with a GET request. Hence, if the user now decides to switch language, an invalid GET request will be sent to the server.
Any ideas how to solve this?
To be a little more specific: I'm running into this problem in Rails 3.0.9 on the registration form of Devise (1.4.2)
I often write my own routes to avoid the exact problem you are describing. I think it's a big flaw in Rails routing.
You may be able to change the Devise routes, and the rest of your resource routes, so that your GET and POST URLs look identical. Here's an example of what I mean.
scope '/posts' do
get '/:id/edit' => "posts#edit", :as => "edit_posts"
post '/:id/edit' => "posts#update", :as => "update_posts"
end
It's a bit more work doing things that way, though.
You could always disable the locale select for the pages where you have problems.
You could check with javascript if there is a .fieldWithError classed element on the page. If so, you can be sure that the last request was POST. In that case, you would have to change the 'action' attribute for the form (change the locale) and submit it again.
You can not access the HTTP method of the current response with javascript.
@WizardofOgz thanks for putting me on the right track. I'm adding this answer, so that I can paste in some code, which I can't in a comment, but I'll accept your answer.
I found this related post specifically for Devise. I've tested it on the password reset routes and this seems to work fine (although I guess this isn't complete yet):
devise_for :user, :path_names => { :sign_up => "register", :sign_in => 'login', :sign_out => 'logout' }, :skip => [:passwords] do
scope :controller => 'devise/passwords' do
post :create, :path => 'user/password/new', :as => :user_password
get :new, :path => 'user/password/new' , :as => :new_user_password
end
end
精彩评论