Is there a standard way in Rails of terminating a request early with
throw or raise?
I am thinking of when a controller invokes a private method and inside
that method I wish to render a result and then finish. For example:
def my_action
...
authorize_something
...
end
private
def authorize_something
...
if some_failure_condition
flash[:error] = "I couldn't do that"
redirect_to :controller=>:top, :action=>:index
throw :request_complete # <<< WHAT GOES HERE?
end
end
that is, without having to put an explicit catch or rescue in every
action which calls authorize_something, and without having to check
the return value from authorize_something everywhere that it is
called.
I have found 'rescue_from'; however this doesn't do what I need
because my Cucumber tests still abort with the exception. That is, it
seems that rescue_from is intended to handle pretty display of error
pages when "real" exceptions occur, not as a mechanism by which a user
exception can signal the early (but successful) termination of a
request.
Is there any other facility I should be looking at?
i don't know if i understand what you need, but i usually put various
checks on a befor_filter. if conditions are not met you will simply
return false and the execution stops.
Why do you need to terminate a request early? Is this an HTTP request?
By "request" I meant "controller action".
Within a method called by the controller action, I want to render
something and then prevent the controller action from continuing any
further (otherwise I'd get a double-render error, and/or the
controller would make changes to the database state which I don't want
it to).
I am aware of before_filter. but in this case I will have gone quite a
long way into the controller action logic before it's known that I
need to terminate this particular request. It doesn't divide neatly
into "pre-condition check" and then "do stuff".
I thought I had seen somewhere that there was a way to terminate a
request early, but I could be thinking of a different framework. In
Sinatra you can 'throw :halt, response'.
If you do want those semantics (perhaps because you're inside one or
more helper methods where it's not so convenient to just render and
return) then it should be easy enough to recreate them with an around
filter.
If you do want those semantics (perhaps because you're inside one or
more helper methods where it's not so convenient to just render and
return) then it should be easy enough to recreate them with an around
filter.
An around_filter with catch and yield would do the job. I hadn't
thought of that, thanks.
Or I might just let the exception bubble upwards to rescue_from, and
test the exception rather than the display. e.g. in Cucumber,
Then /^it should be forbidden if (.*)$/ do |thing|
assert_raises(Forbidden) { When thing }
end