redirect to a route alias on a form validation error
If I'm on a route alias such as /register and I have a form error and I render :new, is it possible for the path to be /register still?
At the moment it is rendering /new
I could do a redirect_to register_path but then I would lose the params?
It's making the following test fail:
Scenario: Try registering with a bad staff number
Given I am on the registration page
When I fill in "email" with "kevin@acme.com"
And I fill in "First Name" with "Kevin"
And I fill in "last name" with "Monk"
And I fill in "Employee Number" with "something barking123"
And I press "Register"
Then I should be on the registration page
And I should see "Your employee ID number looks i开发者_JAVA百科ncorrect."
An alternative would be to set up two "register" routes. One that accepts only GET requests (and goes to the :new action) and the other that accepts only POST requests (and goes to the create action, but renders the same template as for new).
This might look like:
map.get_register 'register', :controller => :registrations,
:action => :new, :conditions => { :method => :get }
map.post_register 'register', :controller => :registrations,
:action => :create, :conditions => { :method => :post }
Then in your controller:
def new
@registration = Registration.new
# renders the 'registrations/new' template
end
def create
@registration = Registration.new(params[:registration])
# render the 'registrations/new' template if we fail validation
return render(:action => :new) unless @registration.save
# otherwise renders the "create" template which is likely a thank-you
end
There seems to be more in a similar vein on this question: Use custom route upon model validation failure
The Rails Way is to render the "new" (i.e. register) action again, since you have created the object, the form will contain the previously entered values as well as error messages. If you redirect, you would have to save the object in the session or the database before doing the redirect. When diverging from convention, it's always good to be sure you're doing so for a good reason.
Calling render from an action will mean that the URL will remain unchanged from whatever was GET'd or POST'd. The reason the URL is /new is because 'Register' must be POST'ing to /new. If you want this feature to pass, you should change "Then I should be on the registration page" to be "Then I should be on the new registration page" and write the corresponding web step, in my opinion.
If you really want this, then you could merge your 'create' action into your 'new' action, and your 'update' action into your 'edit' action. You'd then need to check the request type and handle it accordingly.
This would achieve what you're asking for. Also, people would be able to use the "error" URL and still go to a valid page. That is, even after getting an error, they could copy/paste the URL and there'd be a valid GET page for it.
That being said, this is a major hack and not something I recommend you do. You'll have to do a lot of legwork and the upside is tiny.
Edit: example..
def new
if request.get?
@user = User.new
elsif request.post?
@user = User.new(params[:user])
if @user.save
redirect_to users_path
else
render :new
end
end
end
You'd also need to add custom routes.
Really, this looks like a one line fix in the test. (Why do you prefer being on the /register page?).
If it's really important, you could also stash params in the session var temporarily.
精彩评论