Gandalf StormCrow
Gandalf StormCrow

Reputation: 26212

Double render error rails

Not sure how its possible to get this error :

AbstractController::DoubleRenderError users#create

When in my controller I got this code :

render 'new' and return

I got the log from the bugsnag saying that I got the error at this line.

This is the create method code :

def create
    back_button and return if params[:back_button]

    @profile = current_user.build_profile(params[:user])

    if @profile.nil? || current_user.nil? || @profile.user.nil?
      sign_out
      redirect_to signup_path and return
    end

    if @profile.new_record?
      render 'new' and return
    else
      redirect_to more_questions_path and return
    end
end

I have before filter in this controller :

before_filter :signed_in_user

def signed_in_user
      unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
      end
    end

Upvotes: 14

Views: 27745

Answers (4)

Coenwulf
Coenwulf

Reputation: 1937

The and isn't doing anything for you.

In each place where you have xxx and return, replace it with

xxx
return

For example:

redirect_to signup_path
return

That should work more like you would expect it to.

Upvotes: 6

fotanus
fotanus

Reputation: 20116

I suppose redirect_to signup_path is returning either nil or false, thus your and return is not being executed.

You can fix this many ways, the simplest is replace

redirect_to signup_path and return

by

redirect_to signup_path
return

Yet, I suggest you to do a bigger change. Try changing this

if @profile.nil? || current_user.nil? || @profile.user.nil?
  sign_out
  redirect_to signup_path and return
end

if @profile.new_record?
  render 'new' and return
else
  redirect_to more_questions_path and return
end

By

if @profile.nil? || current_user.nil? || @profile.user.nil?
  sign_out
  redirect_to signup_path
elsif @profile.new_record?
  render 'new'
else
  redirect_to more_questions_path
end

This way it is clear that only one path can be taken, without relying on return.

Upvotes: 0

Thomas Klemm
Thomas Klemm

Reputation: 10856

Give this a try:

class UsersController < ApplicationController
  before_filter :signed_in_user

  def create
    return back_button if params[:back_button]

    @profile = current_user.build_profile(params[:user])

    if @profile.nil? || current_user.nil? || @profile.user.nil?
      sign_out
      return redirect_to signup_path
    end

    if @profile.new_record?
      render 'new'
    else
      redirect_to more_questions_path
    end
  end

  private

  def signed_in_user
    unless signed_in?
      store_location
      return redirect_to signin_url, notice: "Please sign in."
    end
  end
end

The reasoning behind it: x and return means x and return nil, thus returns nil. Actually, you try to short-circuit the controller action, and return redirect_to ....

Upvotes: 18

cbrulak
cbrulak

Reputation: 15639

You have a render and a redirect. You have to pick one.

Upvotes: 3

Related Questions