开发者

Rails validation conditional redirect

开发者 https://www.devze.com 2023-02-08 22:13 出处:网络
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

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.

0

精彩评论

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

关注公众号