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.