Ruby On Rails'deki bir önceki sayfaya nasıl yönlendirilirsiniz?


186

Sıralanabilir üstbilgileri ve sayfalandırması olan tüm projeleri listeleyen bir sayfam var.

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

Projelerden birini düzenlemeyi seçiyorum

path:
projects/436/edit

Bu sayfada kaydet'i tıkladığımda, proje denetleyicisi / güncelleme yöntemini çağırır. Kodu güncelledikten sonra, belirli bir projeyi düzenlemeyi tıklatmadan önce bulunduğum yola yönlendirmek istiyorum. Başka bir deyişle, aynı sıralama ile aynı sayfada olmak istiyorum.

Ben link_to (: geri) gördüm ve düşündüm: geri redirect_to (: geri) çalışabilir, ama bu bir gitmek.

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

Bunu nasıl çalıştırabileceğim konusunda herhangi bir fikir. Kolayca çözülebilecek bir sorun gibi görünüyor, ama RoR için yeniyim.

Yanıtlar:


323

Düzenleme işleminizde, istekte bulunan url'yi, birden fazla istekte bulunan oturum karmasına kaydedin:

session[:return_to] ||= request.referer

Ardından, başarılı bir kaydetme işleminden sonra güncelleme işleminize yönlendirin:

redirect_to session.delete(:return_to)

68
redirect_to session.delete(:return_to)Güncelleme işleminde öneririm . Artık gerekli olmadığından, oturumdaki değeri temizler.
— stigi

19
birkaç sekmenin açık olmaması bu mantığı karıştırmaz mı?
— jones

12
Sadece yapamaz mıydın redirect_to request.referer?
— Elle Mundy

1
@DanMundy Hayır, bunun mümkün olması için çalışması için olması gerekir request.referer.referer. @Jaime Bellmyer Neden ||=?
— x-yuri

@jones evet. Başka bir model düzenlemesine geçerseniz de karışıklık var. Ben de neden ilgileniyorum || =
— Mauro

99

Neden redirect_to(:back)senin için çalışmıyor , neden hiç uğraşmıyor?

redirect_to(:back)benim için bir cazibe gibi çalışıyor. Sadece kısa bir yol redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/rails/ActionController/Base/redirect_to (Rails 3 öncesi) veya http://apidock.com/rails/ActionController/Redirecting/redirect_to (Rails 3)

redirect_to(:back)Rails 5'te kullanımdan kaldırıldığını lütfen unutmayın.

redirect_back(fallback_location: 'something')bunun yerine (bkz. http://blog.bigbinary.com/2016/02/29/rails-5-improves-redirect_to_back-with-redirect-back.html )


12
redirect_to :backbenim için de iyi çalışmıyor, ziyaret ettiğinizi söylüyoruz /posts/new, bu bir sonraki istek için referans olarak ayarlandı, bu yüzden form başarıyla gönderildikten sonra formu tekrar gösterir, yani /posts/new. Bununla birlikte, diğer amaçlar için iyi çalışır.
— Kris

Yani OP iki kez geri yönlendirmek istiyor. Eminim sadece yapabilirdi redirect_to projects_path.
— x-yuri

Evet. Rails 5
— strizzwald

@strizzwald "iyi çalışmıyor" ne anlama geliyor? Herhangi bir ayrıntı?
— Pascal

@pascalbetz, Demek istediğim, HTTP_REFERERayarlanmadıysa, ActionController::RedirectBackErrorbu durumda bu istisnayı kurtarmak zorunda kalacağınızdır. Anladığım kadarıyla kullanmak redirect_back, sağlamak zorunda olduğunuz için istisna işlemeyi gerektirmez fallback_location. Belki de 'iyi çalışmıyor' koymanın doğru yolu değildir.
— strizzwald

45

Jaime'nin yöntemini bir istisna dışında seviyorum, referansı her defasında yeniden saklamak benim için daha iyi çalıştı:

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

Bunun nedeni, birden fazla nesneyi düzenlerseniz, her zaman Jaime'nin yöntemiyle oturumda sakladığınız ilk URL'ye yönlendirilirsiniz. Örneğin, Apple ve Orange nesnelerim olduğunu varsayalım. Apple'ı düzenliyorum ve session[:return_to]bu eylemin yönlendirenine ayarlanıyorum. Aynı kodu kullanarak Portakalları düzenlemeye gittiğimde session[:return_to], zaten tanımlandığı için ayarlanmayacak. Portakal'ı güncellediğimde, önceki Apple # düzenleme eyleminin referansına göndereceğim.


evet, ancak yanlışlıkla bulunduğunuz URL aynı şekilde depolandıysa ne yapacağınızı önerebilir misiniz? Sen elmadasın ve elmadan geldin. Ve önceki konumu istiyorsun
— Uko

33

Bizim uygulamada böyle yapıyoruz

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

Bu şekilde yalnızca son GET isteğini :return_tooturum parametresinde saklarsınız, böylece POSTed ile birden çok zaman çalışsa bile tüm formlar :return_to.


3
request.request_uriartık mevcut değil, bu yüzden request.fullpathonun yerine kullanmanızı öneririz
— anka

@anka Güncellendi.
— Yorumunuz

2
evet bu oldukça iyi. Sadece genel olarak kullanmamayı öneririm andve orde ififadeleri. Kullanın &&ve ||bunun yerine. Ayrıntılar burada .
— Aşil

19

Raylarda 5, Ray Kılavuzları'ndaki talimatlara göre şunları kullanabilirsiniz:

redirect_back(fallback_location: root_path)

'Geri' konumu, tarayıcı tarafından ayarlanması garanti edilmeyen HTTP_REFERER başlığından alınır. Bu yüzden bir 'geri dönüş_konumu' sağlamalısınız.


Bu özellik raylar 5'te görünür.
— Chambeur

@pSkarl Kullanıcıya flash mesajla bir sorun olduğunu söylemek için ifade noticeiçeren bir nesneyi nasıl iletebilirim redirect_back?
— alexventuraio

2
Bunu yaparak bunu çözebilirim redirect_back(fallback_location: root_path, notice: "Something went wrong!"). Umarım bir şekilde yardımcı olabilir .
— alexventuraio

18

request.referer Rack tarafından ayarlanır ve aşağıdaki gibi ayarlanır:

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

Sadece bir yapın redirect_to request.refererve her zaman gerçek yönlendiren sayfaya veya root_path'e ('/') yönlendirecektir. Bu, doğrudan gezinme durumlarında başarısız olan testlerin, kontrolörün bir redirect_to:


Emin değil misiniz at ama raf kaynağına bakarak hangi dosya, bu nasıl olduğu refererhakkındaki olarak tanımlanmıştır 28 Mar 2011 ve bu böyle itibariyle tanımlanmaktadır nasıl bugün . Yani, || '/'tanımın bir parçası değildir.
— maček

1

İlgilenenler için, MBO'nun orijinal yanıtını genişleten uygulamam (raylara 4.2.4, yakut 2.1.5'e karşı yazılmış).

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.