Ayrad
Ayrad

Reputation: 4056

Multiple redirects in my create action causing error

I have some issues with my create action in my multi-step form. I receive an error in the last page when I submit the payment form (render redirect cannot be called twice)

How can I make my create action work with render new and redirect when @post.all_valid? is true?

My controller action looks like this:

 def create
    session[:post_params].deep_merge!(params[:post]) if params[:post]
    @post = Post.new(session[:post_params])
    @post.current_step = session[:post_step]

    if @post.valid?
      if params[:back_button]
        @post.previous_step
      elsif @post.last_step?
          if @post.all_valid?
            @post.save_with_payment 
            flash[:notice] =  'Your post was created successfully' 
            redirect_to @post
          end
      else
        @post.next_step
      end

    session[:post_step] =  @post.current_step
    end

    if @post.new_record?
        render "new"
    else
        session[:post_step] = session[:post_params] = nil
    end
  end

Upvotes: 0

Views: 2012

Answers (2)

CDub
CDub

Reputation: 13354

If you're using multiple render calls or a combination of redirect_to and render, you'll need to specify a return along with all but the last of those calls. Generally, I even use return on the last call as well just to be explicit. The reason is because neither redirect_to or return halt execution, thus why you see the error you are seeing.

Give this a try:

def create
  session[:post_params].deep_merge!(params[:post]) if params[:post]
  @post = Post.new(session[:post_params])
  @post.current_step = session[:post_step]

  if @post.valid?
    if params[:back_button]
      @post.previous_step
    elsif @post.last_step?
      if @post.all_valid?
        @post.save_with_payment 
        flash[:notice] =  'Your post was created successfully' 
        redirect_to @post and return
      end
    else
      @post.next_step
    end

    session[:post_step] =  @post.current_step
  end

  if @post.new_record?
    return render "new"
  else
    session[:post_step] = session[:post_params] = nil
  end
end

Again, the difference between your code and what's above is the and return after the redirect_to and render.

An alternative would be to say return redirect_to ... or return render ..., but I prefer the above because it's more "readable".

Upvotes: 3

Danny
Danny

Reputation: 6025

Just add an "and return" after the first occurence

Upvotes: 1

Related Questions