85 votes

Rails 3: Comment "redirect_to" en appel Ajax?

La suite de attempt_login méthode est appelée à l'aide d'Ajax après un formulaire de connexion est soumis.

class AccessController < ApplicationController
  [...]
  def attempt_login
    authorized_user = User.authenticate(params[:username], params[:password])

    if authorized_user
      session[:user_id] = authorized_user.id
      session[:username] = authorized_user.username
      flash[:notice] = "Hello #{authorized_user.name}."
      redirect_to(:controller => 'jobs', :action => 'index')
    else
      [...]
    end
  end
end

Le problème est qu' redirect_to ne fonctionne pas.

Comment voulez-vous résoudre ce problème ?

101voto

Misha Moroshko Points 20469

Enfin, j'ai juste remplacé

redirect_to(:controller => 'jobs', :action => 'index')

avec ceci:

render :js => "window.location = '/jobs/index'"

et il fonctionne très bien!

64voto

nathanvda Points 25878

Il est très facile de garder le flash pour la prochaine requête. Dans votre contrôleur de faire quelque chose comme

flash[:notice] = 'Your work was awesome! A unicorn is born!'
flash.keep(:notice)
render js: "window.location = '#{root_path}'"

L' flash.keep sera assurez-vous que le flash est gardé pour la prochaine requête. Ainsi, lorsque l' root_path est rendue, il affichera le message flash. Rails est génial :)

27voto

Mike Points 3544

Je pense que c'est un peu plus sympa:

render js: "window.location.pathname='#{jobs_path}'"

26voto

Priit Points 2196

Dans une de mes applications, j'utilise JSON à effectuer sur la redirection, et le flash de message de données. Il ressemblerait à quelque chose comme ceci:

class AccessController < ApplicationController
  ...
  def attempt_login
    ...
    if authorized_user
      if request.xhr?
        render :json => {
          :location => url_for(:controller => 'jobs', :action => 'index'),
          :flash => {:notice => "Hello #{authorized_user.name}."}
        }
      else
        redirect_to(:controller => 'jobs', :action => 'index')
      end
    else
      # Render login screen with 422 error code
      render :login, :status => :unprocessable_entity
    end
  end
end

Et jQuery simple exemple serait:

$.ajax({
  ...
  type: 'json',
  success: functon(data) {
    data = $.parseJSON(data);
    if (data.location) {
      window.location.href = data.location;
    }
    if (data.flash && data.flash.notice) {
      // Maybe display flash message, etc.
    }
  },
  error: function() {
    // If login fails, sending 422 error code sends you here.
  }
})

18voto

Yarin Points 18186

Combinant le meilleur de toutes les réponses:

...
if request.xhr?
  flash[:notice] = "Hello #{authorized_user.name}."
  flash.keep(:notice) # Keep flash notice around for the redirect.
  render :js => "window.location = #{jobs_path.to_json}"
else
...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X