web-dev-qa-db-fra.com

Comment rediriger vers la page précédente dans Ruby On Rails?

J'ai une page qui répertorie tous les projets avec des en-têtes triables et une pagination.

path:
/projects?order=asc&page=3&sort=code

Je choisis d'éditer l'un des projets

path:
projects/436/edit

Lorsque je clique sur Enregistrer sur cette page, il appelle la méthode contrôleur de projets/mise à jour. Après avoir mis à jour le code, je souhaite rediriger le chemin sur lequel je me trouvais avant de cliquer sur Modifier un projet spécifique. En d'autres termes, je veux être sur la même page avec le même tri.

J'ai vu link_to (: back) et j'ai pensé que: back pouvait fonctionner dans redirect_to (: back), mais ce n'est pas possible.

puts YAML::dump(:back) 
yields the following:
:back 

Des idées sur comment je pourrais obtenir que cela fonctionne. Cela semble être un problème qui pourrait être facilement résolu, mais je suis nouveau sur RoR.

178
easement

Dans votre action d'édition, stockez l'URL demandée dans le hachage de session, disponible pour plusieurs demandes:

session[:return_to] ||= request.referer

Puis redirigez-le dans votre action de mise à jour, après une sauvegarde réussie:

redirect_to session.delete(:return_to)
316
Jaime Bellmyer

Pourquoi redirect_to(:back) ne fonctionne-t-il pas pour vous, pourquoi ne pas y aller?

redirect_to(:back) fonctionne comme un charme pour moi. C'est juste un raccourci pour redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/Rails/ActionController/Base/redirect_to (pre Rails 3) ou http://apidock.com/Rails/ActionController/ Redirection/redirect_to (Rails 3)

Veuillez noter que redirect_to(:back) est obsolète dans Rails 5. Vous pouvez utiliser

redirect_back(fallback_location: 'something') à la place (voir http://blog.bigbinary.com/2016/02/29/Rails-5-improves-redirect_to_back-with-redirect-back.html )

97
Pascal

J'aime la méthode de Jaime à une exception près, cela a mieux fonctionné pour moi de ré-enregistrer le référant à chaque fois:

def edit
    session[:return_to] = request.referer
...

La raison en est que si vous modifiez plusieurs objets, vous serez toujours redirigé vers la première URL que vous avez enregistrée dans la session avec la méthode de Jaime. Par exemple, supposons que j’ai les objets Apple et Orange. J'édite Apple et session[:return_to] est défini sur le référent de cette action. Quand je vais éditer des oranges en utilisant le même code, session[:return_to] ne sera pas défini car il est déjà défini. Ainsi, lorsque je mettrai à jour Orange, je serai envoyé au référent de la précédente action Apple # edit.

45
Tony

Voici comment nous le faisons dans notre application

def store_location
  session[:return_to] = request.fullpath if request.get? and controller_name != "user_sessions" and controller_name != "sessions"
end

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

De cette façon, vous ne stockez que la dernière requête GET dans le paramètre de session :return_to, de sorte que tous les formulaires, même lorsque POSTed a plusieurs heures, fonctionnent avec :return_to.

33
MBO

request.referer est défini par le rack et se présente comme suit:

def referer
  @env['HTTP_REFERER'] || '/'
end

Faites juste un redirect_to request.referer et il sera toujours redirigé vers la vraie page de référence, ou le chemin_racine ('/'). Ceci est essentiel lorsque les tests échouent en cas de navigation directe vers une page particulière dans laquelle le contrôleur envoie une redirection_to: retour

18
Steve Tipton

Dans Rails 5, conformément aux instructions de Rails Guides, vous pouvez utiliser:

redirect_back(fallback_location: root_path)

L'emplacement 'back' est tiré de l'en-tête HTTP_REFERER, qui n'est pas nécessairement défini par le navigateur. C'est pourquoi vous devriez fournir un 'emplacement de repli'.

15
pSkarl

Pour ceux qui sont intéressés, voici mon implémentation qui étend la réponse originale de MBO (écrite contre Rails 4.2.4, Ruby 2.1.5).

class ApplicationController < ActionController::Base
  after_filter :set_return_to_location

  REDIRECT_CONTROLLER_BLACKLIST = %w(
    sessions
    user_sessions
    ...
    etc.
  )

  ...

  def set_return_to_location
    return unless request.get?
    return unless request.format.html?
    return unless %w(show index edit).include?(params[:action])
    return if REDIRECT_CONTROLLER_BLACKLIST.include?(controller_name)
    session[:return_to] = request.fullpath
  end

  def redirect_back_or_default(default_path = root_path)
    redirect_to(
      session[:return_to].present? && session[:return_to] != request.fullpath ?
        session[:return_to] : default_path
    )
  end
end
1
aschyiel