Can only render or redirect once per action - why?


#1

I ran into this error message a quite a few times since my app requires
branching to different pages from the same action… say using a switch
statement. Ofcourse I found that you can use multiple redirects or
renders
if you do

render :action => ‘new’ and return false

I hate to code something I don’t understand fully. Any explanation of
this
will be greatly appreciated!

Thanks,

bakki kudva


#2

How would one send output to the browser twice? (minus ajax usuage of
course) Thats really the simple reasoning behind it. The render tells
rails what to send back to the browser and hence, only has one shot at
it*.

If you need to render another view from your current action, here’s
the common approach:

def first_action
if some_condition
render :action => :second_action #renders the second action_view
but doesn’t actually call the second_action method
end
#otherwise it will just render the first_action view
end

def second_action
if something
redirect_to :action => “first_action”
else
render :layout => false #just an example of rendering with no
layout
end
end

Hope this helps some.
-Nick


#3

Nick,

Thanks for the quick repy. I realize you wouldn’t send output to the
browser
twice. For example in the following code…

def create
@user = User.new(params[:user])
@confirm = params[:confirm]
unless @user.password == @confirm
flash[:notice] = ‘Password mismatch. Please type them again.’
render :action => ‘new’ and return false
end
if @user.save
flash[:notice] = ‘Student was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

I get the error because of the render statement within the unless —
end
block. I had assumed that a render statement terminates the action. But
it
apparently does not unless you explicitly tell it to with the return
statement. I wonder if there is any reason for this. Doesn’t a render
sort
of imply that you are done with the action, just like the redirect_to
and
any statements following it wouldn’t be reached?

bakki


#4

On 1/10/06, Bakki K. removed_email_address@domain.invalid wrote:

   render :action => 'new' and return false

block. I had assumed that a render statement terminates the action. But it

rails what to send back to the browser and hence, only has one shot at
#otherwise it will just render the first_action view

http://lists.rubyonrails.org/mailman/listinfo/rails

Render doesn’t return, for reverse-compatibility reasons.


Kyle M.
Chief Technologist
E Factor Media // FN Interactive
removed_email_address@domain.invalid
1-866-263-3261


#5

I think it is for the case where you want to redirect a user because
he/she is not authorized:

unless user.authorized?
redirect_to …
end

render …

The render call would be executed and if the user blocked the redirect
he/she would be able to see the page.

And validations should be in your model anyway. There is
validates_confirmation_of for this password-confirmation :wink:


#6

Good point Jules, Thanks for pointing that out. I am still cutting my
teeth
on this :slight_smile:

-bakki


#7

That’s what I was thinking…so why does rails give me the error
message? It
should not see the redirect_to below right?

-bakki


#8

It could either be seeing the redirect OR the render. Either one will
give you the error message. The way you have it setup now is that if
the first render is seen in the unless you will ALWAYS see another
render (either redirect in the if, or the render with your else).
Throw a return statement after the unless render and you’ll be good to
go, or restructure it so its only got one exit point.