The DoubleRenderError exception recently introduced is forcing me to go back and rewrite my apps authentication handler. Before I could do a redirect right in the middle of a request. Whatever was happening after that went unnoticed, I assumed it was simply ending the request after the redirect was called, but apparently it was going on and rendering the page. Why can''t a redirect simply halt execution of the action? Is there a way to rescue the exception outside of the controller and gracefully exit? -Jeff _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
>Whatever was happening after that went unnoticed, I assumed it was simply > ending the request after the redirect was called, but apparently it was going > on and rendering the page.If you do your authentication in a before_filter (which you probably should, unless you have a specific reason not to), just return false from the filter and execution will stop. That''s how the login generator does it... If your authentication code doesn''t return false, exit, throw an exception, or do something drastic like that, you should probably alter it so it does. I''ve seen too many php scripts that do authentication by something like if(!$_SESSION["logged_in"]) { header("Location: login.php"); } When you hit that page and you''re not logged in, you do get redirected. If you modify your user-agent to ignore http redirects, however, you can see the page''s content just fine, even if you''re not logged in. Just something to be aware of :) Tyler
Well it is not just my authentication handler, things have broken all over
my application...
I''ll do stuff like this
def generic_action
@data = @order.generic_data ||= GenericData.new
if @request.post?
@data.attributes = @params[''data'']
redirect_to :action => next if @data.save
end
end
Now I have to "return redirect_to" everywhere instead. It''s
just clutter. I
think if I were able to rescue the exception at some good place without
modifying the base libraries, perhaps with a configuration option, I could
keep my code nice and simple and not have to return out of the action.
Or, it could simply not render anything after the first one, instead of
throwing the exception. I can think of some instances when I would actually
want to render multiple pages. It just seems like an unnecessary limitation.
What purpose does it serve? Was it added to facilitate something else?
I''d
like a simple way to revert back to the old behavior.
-Jeff
----- Original Message -----
From: "Tyler Kiley"
<tyler.kiley-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: <rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org>
Sent: Wednesday, July 06, 2005 3:29 PM
Subject: Re: [Rails] DoubleRenderError exception
>Whatever was happening after that went unnoticed, I assumed it was simply
> ending the request after the redirect was called, but apparently it was
> going
> on and rendering the page.
If you do your authentication in a before_filter (which you probably
should, unless you have a specific reason not to), just return false
from the filter and execution will stop. That''s how the login
generator does it...
If your authentication code doesn''t return false, exit, throw an
exception, or do something drastic like that, you should probably
alter it so it does. I''ve seen too many php scripts that do
authentication by something like
if(!$_SESSION["logged_in"]) { header("Location: login.php");
}
When you hit that page and you''re not logged in, you do get
redirected. If you modify your user-agent to ignore http redirects,
however, you can see the page''s content just fine, even if
you''re not
logged in.
Just something to be aware of :)
Tyler
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails
> def generic_action > @data = @order.generic_data ||= GenericData.new > if @request.post? > @data.attributes = @params[''data''] > redirect_to :action => next if @data.save > end > endThis should continue to work, I have stuff like this all over my application which has been running on edge rails for a while.> Or, it could simply not render anything after the first one, instead of > throwing the exception. I can think of some instances when I would actually > want to render multiple pages. It just seems like an unnecessary limitation. > What purpose does it serve? Was it added to facilitate something else? I''d > like a simple way to revert back to the old behavior.This behaviour has never worked. The only difference now is that instead of failing silently, we tell you that something isn''t working. render_text "aaa" render_text "BBB" has never rendered "aaaBBB" -- Cheers Koz
Some more commentary on this: http://tech.rufy.com/entry/61 On Jul 6, 2005, at 5:29 PM, Michael Koziarski wrote:>> def generic_action >> @data = @order.generic_data ||= GenericData.new >> if @request.post? >> @data.attributes = @params[''data''] >> redirect_to :action => next if @data.save >> end >> end >> > > This should continue to work, I have stuff like this all over my > application which has been running on edge rails for a while. > > >> Or, it could simply not render anything after the first one, >> instead of >> throwing the exception. I can think of some instances when I >> would actually >> want to render multiple pages. It just seems like an unnecessary >> limitation. >> What purpose does it serve? Was it added to facilitate something >> else? I''d >> like a simple way to revert back to the old behavior. >> > > This behaviour has never worked. The only difference now is that > instead of failing silently, we tell you that something isn''t working. > > render_text "aaa" > render_text "BBB" > > has never rendered "aaaBBB" > > -- > Cheers > > Koz > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Duane Johnson
2005-Jul-07 14:41 UTC
How about a redirect_to! method? (was Re: DoubleRenderError exception)
May I suggest a redirect_to! method?
Here is some code I picked off the RAA, called "ruby-goto":
## goto.rb
STACK = []
class Label
attr_accessor :name;
attr_accessor :block;
def initialize(name, block);
@name = name
@block = block
end
def ==(sym)
@name == sym
end
end
class Goto < Exception;
attr_accessor :label
def initialize(label); @label = label; end
end
def label(sym, &block)
STACK.last << Label.new(sym, block)
end
def frame_start
STACK << []
end
def frame_end
frame = STACK.pop
idx = 0
begin
for i in (idx...frame.size)
frame[i].block.call if frame[i].block
end
rescue Goto => g
idx = frame.index(g.label)
retry
end
end
def goto(label)
raise Goto.new(label)
end
And from the goto_test.rb file:
## goto_test.rb
require ''goto''
def test
frame_start
label(:start) { goto :b }
label(:a) { print "world!\n"; goto :c }
label(:b) { print "hello "; goto :a }
label(:c)
frame_end
end
frame_start
label(:a) { test }
label(:b) { goto :a }
frame_end
Does this seem like a viable solution?
Duane Johnson
(canadaduane)
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails
Jeff,> def generic_action > @data = @order.generic_data ||= GenericData.new > if @request.post? > @data.attributes = @params[''data''] > redirect_to :action => next if @data.save > end > endThat will work. I''m assuming that you''re running into problems because you have an explicit render call at the bottom of your generic_action. If you rely on rails'' implicit rendering, you''re fine, but if you call it yourself, you get the exception. My only beef with the DoubleRenderException is that a redirect_to counts as a render, which is kinda non-intuitive the first time you run into it. It took me a while to figure that out.