Login forms , redirect_to and ajax-scaffold problems

Hi,

I have a standard type authentication technique direct from AWDWR, so
there is a

before_filter :authorize_employee, :except => :login in my
employees_controller.rb

the authorize_employee is in application.rb

 def authorize_employee
    unless session[:employee_id]
        flash[:notice] = "Please log in"
        # save the URL the user requested so we can hop back to it
        # after login
        session[:jumpto] = request.parameters
        redirect_to(:controller => "employees", :action => "login")
    else
        logger.info "User already authorized as 

#{session[:employee_id]}"
end
end

All standard stuff and works as expected most of the time.

Now the problem is that if the session expires and someone clicks on say
the Create New
link in the ajax-scaffold (of a page that was already sitting there from
last time), I
get the redirect_to :controller => ‘employees’, :action => ‘login’, but
the resulting
form gets inserted into the existing page as if it were a response from
an ajax request,
but a redirect_to is not generating an ajax request and I expect a new
page to be
generated with the login form.

I have been playing with this for hours now, and cannot figure out how
to get it to put
up a fresh login screen.

Any ideas anyone?

Thanks

very good question

I think the good option is to use built-in :failure attribute of
link_to_remote that can call redirect function in case of failure

now, it only triggers if the HTTP response is 3xx as oppossed to 2xx
for example you way want to do this instead of redirect_to

render_text ‘’, ‘307 Temporary Redirect’

of course, you need to be sure to use this response only in case of ajax
request so that regular request is handled by standard redirect_to

hope this at least points to the right direction and you can get a
working
code out of this

sorry, this syntax is deprecated

should be like

render :nothing => true, :status => 307

http://api.rubyonrails.com/classes/ActionController/Base.html#M000178

Thanks for the response,

I have tried playing with that, I am not sure if it is an ajax_scaffold
problem or not but I can’t get it to work, I even tried this…

<%= link_to_remote “Create New”,
:url => { :controller => ‘employees’, :action => ‘new’ },
302 => “document.location =
request.getResponseHeader(‘location’)”,
:loading => “AjaxScaffold.newOnLoading(request,‘employee’);”,
:success => “AjaxScaffold.newOnSuccess(request,‘employee’);”,
:failure => “AjaxScaffold.newOnFailure(request,‘employee’);”,
:href => url_for(:controller => ‘employees’, :action => ‘new’),
:class => “create” %>

Notice the 302 => this is meant to force a redirect, but I always get
the same thing, the login page gets rendered into the existing page.

Maybe I should ask, how do I force a page refresh when an outstanding
ajax call fails? or gets redirected?

Ok I finally got it thanks…

For anyone else reading this I had to put this in my controller…

render :layout => false, :status => 302 if request.xhr?

and this in my link_to_remote in the rhtml…

|* 302 => “document.location = ‘/employees/login’”,

as in
*|

|* <%= link_to_remote “Create New”,
{ :url => { :controller => ‘employees’, :action => ‘new’ },
302 => “document.location = ‘/employees/login’”,
:loading => “AjaxScaffold.newOnLoading(request,‘employee’);”,
:success => “AjaxScaffold.newOnSuccess(request,‘employee’);”,
:failure => “AjaxScaffold.newOnFailure(request,‘employee’);” },
{ :href => url_for(:controller => ‘employees’, :action => ‘new’),
:class => “create” }%>
*|

I had to hard code the redirection, it would be nice to be able to use
redirect_to, but that simply doesn’t work and doesn’t return a response
code of 302 to the ajax handlers.

Thanks,

I did try redirect_to, however for some reason the ajax callback does
not see it as an error or a redirect but as success, I tried many
different things and the one that worked was the render :layout =>
false, :status => 302 if request.xhr?. This could be a bug in the ajax
stuff I guess.

In my case I need to distinguish between failures (>=500) and redirects
as the ajax scaffold uses errors >= 500 for error messages, and using
redirect allows me to catch the login failure specifically.

Good to hear it works - it is easier to simplify now :slight_smile:

Did not try it, but I guess this should work too

<%= link_to_remote “Create New”,
{ :url => { :controller => ‘employees’, :action => ‘new’ },
:loading => “AjaxScaffold.newOnLoading(request,‘employee’);”,
:success => “AjaxScaffold.newOnSuccess(request,‘employee’);”,
:failure => “document.location = ‘/employees/login’” },
{ :href => url_for(:controller => ‘employees’, :action =>
‘new’),
:class => “create” }%>

You don’t need to hardcode 302 in view as any 3xx is failure.
By the way, I have just re-checked docs and see that redirect_to also
generates 302 header, so you may want to simply try adding :failure
attribute to the link and see if it works with no changes to
controller…