Разработайте и сохранено_для_для: как вы храните место возврата? - PullRequest
27 голосов
/ 17 мая 2011

У меня есть страница, путь которой (например) / помещения / 92, на которой я показываю «пожалуйста [войдите] или [зарегистрируйтесь] для получения дополнительной информации», если пользователь не вошел в систему, и я хочу придумать вернуть ту же самую страницу / помещения / 92 после того, как пользователь войдет в систему.

Я читал другие посты и думаю, что понимаю, как устройство stored_location_for должно работать. Теоретически я мог бы поместить что-то вроде этого в мой ApplicationController:

def stored_location_for(resource)
  if (r = session[:return_to])
    session[:return_to] = nil
    r
  else
    super
  end
end

У меня вопрос: как / где мне установить сессию [: return_to]?

Я хочу установить сессию [: return_to], только если пользователь нажимает [войти] или [зарегистрироваться], но какой лучший способ сделать это?

  • Украсить ссылки с помощью JavaScript? Это может сработать, но, кажется, неуклюже.
  • Установить его в Premises Controller перед рендерингом страницы? Это не кажется правильным: что, если пользователь не нажимает на ссылки [войти] или [зарегистрироваться]? Затем у меня для сеанса [: return_to] установлено какое-то странное значение, которое может сбить меня с толку, если пользователь войдет в систему с какой-либо другой страницы.
  • Добавить строку запроса ?return_to=/premises/92 в ссылки [log in] и [register], обнаружить ее в RegistrationsController и SessionsController и использовать эту информацию для настройки сеанса [: return_to]? Кажется, что это сработало бы, но также и жестко.

Ни один из них не пахнет правильно. Каков общепринятый метод для установки состояния для хранимого расположения_файла_for

Ответы [ 5 ]

25 голосов
/ 30 октября 2011

Разработать использование

session["#{scope}_return_to"]

Таким образом, вы можете использовать session["user_return_to"], если ваша модель для аутентификации - Пользователь.

8 голосов
/ 06 февраля 2014

Я нахожу всю эту вещь перенаправления устройства довольно запутанной.

Когда @rorra говорит, что Devise использует session["#{scope}_return_to"], он означает, что Devise по умолчанию after_sign_in_path_for(resource) будет использовать эту переменную через метод stored_location_for(resource).

Таким образом, вы должны сохранить местоположение, которое вы хотите сохранить, в переменной session["#{scope}_return_to"], которая обычно будет session["user_return_to"].Для этого поместите в ваш application_controller.rb следующее:

after_action :store_location

def store_location
  # store last url - this is needed for post-login redirect to whatever the user last visited.
  if (request.fullpath != "/users/sign_in" &&
      request.fullpath != "/users/sign_up" &&
      request.fullpath != "/users/password" &&
      request.fullpath != "/users/sign_out" &&
      !request.xhr?) # don't store ajax calls
    session["user_return_to"] = request.fullpath 
  end
end

В некоторых случаях вам не нужно будет определять метод after_sign_in_path_for(resource), так как метод devise по умолчанию будет выполнять все перенаправления за вас, и если ихURL перенаправления недоступен, вы будете перенаправлены на корневой путь ресурса (обычно это корневой путь пользователя), а если он не существует, вы будете перенаправлены на корневой путь.Однако если вы хотите настроить, куда отправляется пользователь, если URL-адрес перенаправления недоступен, добавьте следующее в ваш application_contorller.rb (и соответственно измените root_path):

def after_sign_in_path_for(resource)
  stored_location_for(resource) || root_path
end
6 голосов
/ 19 ноября 2011

Devise ищет ключ "#{resource}_return_to" в сеансе.

Здесь я цитирую API:

По умолчанию сначала он пытается найти действительный #{resource}_return_to введите сеанс, затем он возвращается к #{resource}_root_path, в противном случае используется root_path.

Вот ссылка на API

4 голосов
/ 13 ноября 2012

вот лучшее, что я мог придумать. Прекрасно работает также с аутентификацией в Facebook. добавив больше ограничений к добавлению URL к переменной сеанса, вы можете удалить все больше и больше путей, которые пользователь не должен возвращать (например, обратные вызовы, заставки, целевые страницы и т. д.)

#ApplicationsController

after_filter :store_location

def store_location
  session[:previous_urls] ||= []
  # store unique urls only
  session[:previous_urls].prepend request.fullpath if session[:previous_urls].first != request.fullpath && request.fullpath != "/user" && request.fullpath != "/user/login" && request.fullpath != "/" && request.fullpath != "/user/logout" && request.fullpath != "/user/join" && request.fullpath != "/user/auth/facebook/callback"
  # For Rails < 3.2
  # session[:previous_urls].unshift request.fullpath if session[:previous_urls].first != request.fullpath 
  session[:previous_urls].pop if session[:previous_urls].count > 3
end

def after_sign_in_path_for(resource) 
  @url = session[:previous_urls].reverse.first
  if @url != nil
    "http://www.google.com" + @url
  else
    root_path
  end
end
1 голос
/ 17 мая 2011

Мне так нравится:

class ApplicationController < AC::Base
  after_filter :clear_attached_unit # UPDATED

  protected
  def clear_attached_unit
    session[:attached_unit_path] = nil unless keep_attached_unit_path?
  end

  def keep_attached_unit_path? # UPDATED
    @keep_attached_unit_path   
  end                           
end


class UnitController < ApplicationController
  before_filter :attach_unit, :only => [:show]

  protected
  def attach_unit
    session[:attached_unit_path] = request.url if request.get? && !request.xhr?
  end
end

class SessionsController < Devise::SessionsController
  before_filter :keep_attached_unit_path! # UPDATED

  protected
  def keep_attached_unit_path! # UPDATED
    @keep_attached_unit_path = true
  end

  def after_sign_in_path_for(resource_or_scope)
    if resource_or_scope.is_a?(User) && session[:attached_unit_path].present?
      session[:attached_unit_path]
    else
      super
    end
  end 
end

И распакуйте это в модуль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...