Justin Meltzer
Justin Meltzer

Reputation: 13548

Redirect not working

I have this line in my votes controller:

before_filter :authenticate

So when I vote while logged out, it should fail this filter.

My authenticate method in my application controller looks like this:

def authenticate
    logged_in? ? true : access_denied
end

So it returns access_denied which looks like this:

def access_denied
    redirect_to login_path, :notice => "You must log in to perform this action." and return false
end

Therefore, I should be redirected to my login page, right?

I have this in my routes.rb file:

match '/login' => "sessions#new", :as => "login"

and I have a new view with a login form that I should be redirected to when I vote and I'm not logged in. I also have this code in the create method of my votes controller:

if @vote.save
    respond_to do |format|
      format.html { redirect_to @video }
      format.js
    end
  else
    respond_to do |format|
      format.html
    end
  end

But when I vote, I am not redirected, and I get this error message in my logs:

Started GET "/login" for 127.0.0.1 at Thu Mar 24 21:18:08 -0700 2011
  Processing by SessionsController#new as JS
Completed   in 17ms

ActionView::MissingTemplate (Missing template sessions/new with {:locale=>[:en, :en], :formats=>[:js, "*/*"], :handlers=>[:rhtml, :rxml, :erb, :builder, :rjs]} in view paths "/rubyprograms/dreamstill/app/views"):

Why is this happening, and how can I make this redirect work?

Upvotes: 4

Views: 2591

Answers (2)

chris
chris

Reputation: 4351

Since the request that is causing problems is ajax try adding a check within your before_filter to whether the request is js.

if request.xhr?
    render :text => "document.location = '#{login_path}';", :layout => false
else
  redirect_to login_path, ...
end

Upvotes: 1

Pan Thomakos
Pan Thomakos

Reputation: 34350

It seems like you are making a javascript request to your VotesController#create action, but you are missing a JS template for Sessions#new.

Here's what happens: you make a call to VotesController#create as a JS call, and when the user is logged in all is fine, because VotesController#create response to javascript actions. The problem is that if the user is not logged in, the request redirects to SessionsController#new, and the request is still a javascript request. The problem is that SessionsController#new does not respond to JS so you get a missing template error.

I would recommend adding an app/views/sessions/new.js.erb file to handle the JS call. You probably only have an app/views/sessions/new.html.erb file right now.

You can also handle this case by redirecting, using javascript, to an HTML request. You can do this by adding the following to your new.js.erb template:

window.location = "<%= escape_javascript(login_path) %>";

This will basically tell the browser to redirect to the login_path as if the request were an HTML request, instead of a Javascript request.

Upvotes: 6

Related Questions