Thực hiện đúng redirect_to: quay lại Ruby on Rails khi liên kết giới thiệu không có sẵn


91

Tôi đang gặp vấn đề với redirect_to :back. Có, đó là người giới thiệu.

Tôi thường bị ngoại lệ

(ActionController :: RedirectBackError) "Không có HTTP_REFERER nào được đặt trong yêu cầu đối với hành động này, vì vậy không thể gọi thành công redirect_to: back. Nếu đây là thử nghiệm, hãy đảm bảo chỉ định request.env [\" HTTP_REFERER \ "]."

Tôi nhận thấy rằng đây là kết quả của một liên kết giới thiệu không có sẵn. Có cách nào, chẳng hạn, người ta có thể đặt một biến phiên trên mỗi lần truy cập với trang cuối cùng được truy cập và khi HTTP_REFERER không khả dụng, hãy sử dụng biến phiên này để chuyển hướng đến?


Tôi gặp lỗi tương tự trong một hành động cập nhật, điều này thật kỳ lạ vì liên kết giới thiệu không được để trống (như yêu cầu từ biểu mẫu), nhưng một số người dùng đã cố gắng thực hiện điều này mà tôi không biết làm thế nào.
lulalala

Câu trả lời:


144

Nó không chắc rằng bạn làm có một phiên làm việc và không có một giới thiệu.

Tình huống mà người giới thiệu không được thiết lập không phải là hiếm và tôi thường giải cứu điều đó:

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

Nếu bạn làm điều này thường xuyên (mà tôi nghĩ là một ý tưởng tồi), bạn có thể kết hợp nó trong một phương pháp khác như Maran gợi ý.

BTW Tôi nghĩ đó là một ý tưởng tồi vì điều này làm cho luồng người dùng trở nên mơ hồ. Chỉ trong trường hợp đăng nhập, điều này là hợp lý.

CẬP NHẬT : Như một số người đã chỉ ra rằng điều này không còn hoạt động với Rails 5. Thay vào đó, hãy sử dụng redirect_back, phương pháp này cũng hỗ trợ dự phòng. Sau đó, mã trở thành:

def some_method
  redirect_back fallback_location: root_path
end

4
Tôi nghi ngờ rằng tôi sẽ thay đổi điều này để sử dụng Rescue_from thay thế.
Bob Aman

1
@BobAman IMO mà chúng tôi có thể sử dụng rescue_fromnếu bộ điều khiển có nhiềuredirect_to :back
Theo B

không hoạt động với rails 5, ActionController :: RedirectBackError là không xác định ... giải pháp nào?
Matrix

Sử dụng cái này thay thế:redirect_to (request.referrer || root_url)
Abhi

38

Đây là phương thức redirect_to_back nhỏ của tôi:

  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

Bạn có thể chuyển một url tùy chọn để chuyển đến một nơi khác nếu http_refferrer trống.


37
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

Hãy thử điều đó! (Cảm ơn plugin Authlogic )


22
Đây là một giải pháp tốt, nhưng tôi khuyến khích bất kỳ ai sử dụng nó hãy nhớ rằng nó có thể "hỏng" theo cách cực kỳ khó hiểu đối với người dùng nếu họ đang sử dụng nhiều tab để duyệt ứng dụng của bạn.
Mitch Lindgren,

3
+1 Để trả lời câu hỏi và không chỉ trích phương pháp thiết kế.
Abe Petrillo

31

Tính năng cốt lõi

redirect_backlà một tính năng cốt lõi từ Rails 5+, nó có sẵn trong ActionController::Redirectingmô-đun đã được đưa vào ApplicationController::Base.

CẢNH BÁO DEPRECATION: redirect_to :backkhông được dùng nữa và sẽ bị xóa khỏi Rails 5.1. Vui lòng sử dụng redirect_back(fallback_location: fallback_location)nơi fallback_locationđại diện cho vị trí để sử dụng nếu yêu cầu không có thông tin giới thiệu HTTP.

CHỈNH SỬA: nguồn


Liên kết đến nguồn, vui lòng
Chris Bloom

1
@ Chrisbloom7 Đây là thông báo cảnh báo tôi đã gặp khi chạy Rails 5.0.0beta3 với redirect_to :back.
Cyril Duchon-Doris

21

Có lẽ đã muộn nhưng tôi muốn chia sẻ phương pháp của tôi cũng bảo vệ các tùy chọn:

  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

Bạn có thể sử dụng nó như:

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

14

đã cập nhật: Rails 5 đã thêm phương thức redirect_back ( https://github.com/rails/rails/pull/22506/ ), tốt hơn chỉ cần sử dụng:

redirect_back fallback_location: answer_path(answer), flash: { error: I18n.t('m.errors')}

Đối với các đường ray thấp hơn 5.0 vẫn có thể sử dụng cách cũ bên dưới:

tương tự như câu trả lời của @ troex, hãy thêm câu trả lời này vào trình điều khiển ứng dụng của bạn

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

sau đó sử dụng nó trong bộ điều khiển của bạn

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

0

Gần đây, tôi gặp phải sự cố tương tự khi tôi phải chuyển hướng :backhoặc đến trang cụ thể. Sau khi đi đến rất nhiều giải pháp, cuối cùng tôi thấy điều này đơn giản và dường như giải quyết được vấn đề:


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

Nếu bạn muốn sử dụng thông sessiontin chi tiết, hãy làm điều đó trong phần khác của mã.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.