Rails validation conditional redirect
I am currently having an issue with how Rails is performing and responding to a validation result. I have a user registration form. The user could hit this form in two different places. They could hit the form from the homepage or from users/new
. Both forms will post to the same place as I am trying to keep it DRY.
The users/new
page works as is expected. If the user has a validation issue it will return and populate the form. Where I get a problem is on the home page. If a user has a validation issue it now redirects to the users/new
page. I would much prefer that when on the home page I would return the user to that same page and show the validation results there. Is there a way in the controller to redirect to the form the user was at?
def create
@user = User.new(params[:user])
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" } # I'm think开发者_StackOverflow社区ing I can do something here?
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
end
end
end
I have tried to change the render :action => 'new'
line to redirect to the user url but it hasn't worked. Is there something I'm missing?
First, I would add querystring parameters to the URL it is posting to with the controller and action that it came from with something like this:
# Using form_tag
<%= form_tag user_path(@user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %>
# Using form_for
<%= form_for @user, :url => user_path(@user, :controller_name => controller.controller_name, :action_name => controller.action_name) do %>
Then, you can update that line in the create
action of your controller like this:
render '#{params[:controller_name]}/#{params[:action_name]}'
Update
I just realized that using the code above, will render the correct view the first time validation fails, but if validation fails a second time, it will try to render the users/create
view. If this is the route you want to take, you should not use controller.controller_name
, etc in the view, but assign @controller_name
correctly and use that variable instead. However, this only adds to the 'overkill' comment made by Xavier.
Art's on the right track, but you can't use a redirect, as you need the instance variable @user
that's set in your controller, which'll be lost on a new HTTP request (because ever request is handled by a new, clean controller instance).
But you can use the referer information yourself, and use that to pick the right page to render:
render :action => (request.referer =~ /\/users\/new/)? :new : :index
Note: Another answer popped up while I was posting that suggests adding the old controller / action fields to your form, but that seems like overkill to me - you already have all the information you need in request.referer
.
Hope that helps!
Try redirect_to :back
It's a shorthand for redirect_to(request.env["HTTP_REFERER"])
oops, it only works for success. sorry
well, then you have to check inside the block (after format.html) where he came from (by looking at request.env["HTTP_REFERER"]) and render respective action.
精彩评论