web-dev-qa-db-fra.com

Effectuer correctement redirect_to: back dans Ruby on Rails lorsque le référent n'est pas disponible

J'ai un problème avec redirect_to :back. Oui, ce sont des référents.

J'ai souvent l'exception 

(ActionController :: RedirectBackError) "Aucun HTTP_REFERER n'a été défini dans la requête de cette action. Par conséquent, redirect_to: back ne peut pas être appelé avec succès. S'il s'agit d'un test, veillez à spécifier request.env [\" HTTP_REFERER\"]."

Je me rends compte que cela résulte du fait qu'un référent n'est pas disponible. Existe-t-il un moyen, par exemple, de définir une variable de session sur chaque accès avec la dernière page visitée et, lorsque HTTP_REFERER n’est pas disponible, d’utiliser cette variable de session vers laquelle se rediriger?

89
user67050

Il est peu probable que vous ayez une session et que n'avez pas de référent.

La situation dans laquelle un référent n'est pas défini n'est pas si rare et je sauve généralement cette expection:

def some_method
  redirect_to :back
rescue ActionController::RedirectBackError
  redirect_to root_path
end

Si vous le faites souvent (ce qui, à mon avis, est une mauvaise idée), vous pouvez l’envelopper dans une autre méthode, comme le suggère Maran.

BTW, je pense que c'est une mauvaise idée car cela rend le flux d'utilisateurs ambigu. Ce n'est que dans le cas d'un login.

UPDATE: Comme plusieurs personnes l'ont souligné, ne fonctionne plus avec Rails 5 . Utilisez plutôt redirect_back, cette méthode prend également en charge le repli. Le code devient alors:

def some_method
  redirect_back fallback_location: root_path
end
138
harm

Voici ma petite méthode redirect_to_back:

  def redirect_to_back(default = root_url)
    if request.env["HTTP_REFERER"].present? and request.env["HTTP_REFERER"] != request.env["REQUEST_URI"]
      redirect_to :back
    else
      redirect_to default
    end
  end

Vous pouvez passer une URL optionnelle pour aller ailleurs si http_refferrer est vide.

38
Mirko
def store_location
  session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
  session[:return_to] = nil
end

Essayez ça! (Merci au plugin Authlogic )

37
Maran

Caractéristique principale 

redirect_back est une fonctionnalité essentielle de Rails 5+, elle est disponible dans le module ActionController::Redirecting déjà inclus dansApplicationController::Base.

AVERTISSEMENT DE DEPRECATION: redirect_to :back est obsolète et sera supprimé de Rails 5.1. Veuillez utiliser redirect_back(fallback_location: fallback_location)fallback_location représente l'emplacement à utiliser si la demande ne contient aucune information de référent HTTP.

EDIT: source

25
Cyril Duchon-Doris

Peut-être qu'il est tard mais je voudrais partager ma méthode qui préserve également des options:

  def redirect_back_or_default(default = root_path, *options)
    tag_options = {}
    options.first.each { |k,v| tag_options[k] = v } unless options.empty?
    redirect_to (request.referer.present? ? :back : default), tag_options
  end

Vous pouvez l'utiliser comme:

redirect_back_or_default(some_path, :notice => 'Hello from redirect', :status => 301)
21
troex

similaire à la réponse de @ troex, ajoutez ceci à votre contrôleur d'application

def redirect_back_or_default(default = root_path, options = {})
  redirect_to (request.referer.present? ? :back : default), options
end

puis utilisez-le dans votre contrôleur

redirect_back_or_default answer_path(answer), flash: { error: I18n.t('m.errors')}
12
longkt90

Récemment, j'ai rencontré le même problème où je devais rediriger :back ou vers une page spécifique. Après avoir cherché beaucoup de solutions, j'ai finalement trouvé ceci simple et qui semble résoudre le problème:


if request.env["HTTP_REFERER"].present?
    redirect_to :back
else
    redirect_to 'specific/page'
end

Si vous souhaitez utiliser les détails session, faites-le dans la partie else du code.

0
Rahul Goyal