Хэш сеанса в rails превращается в строку

#ruby-on-rails #session #authentication

#ruby-on-rails #сеанс #аутентификация

Вопрос:

По какой-то причине через некоторое время на моем веб-сайте мой хэш сеанса превращается в строку

 undefined method `admin?' for "#<Visitor:0x000001071b7800>":String
  

это то, что я получаю в своем render_layout методе

 def render_layout
  if session[:visitor].admin?
    render layout: 'admin'
  else
    render layout: 'application'
  end
end
  

единственные два других раза, когда я когда-либо вызывал или использовал session[:visitor], — это мой authenticate метод и мой logged_in? метод, который я использую для пропуска authenticate

 def authenticate
  uuid = params[:uuid]
  @visitor ||= uuid amp;amp; Visitor.find_by_uuid(uuid)
  if !@visitor
    authenticate_or_request_with_http_basic do |login, password|
      @visitor = Visitor.find_by_uuid(ENV['ADMIN_UUID']) if login == 'test' amp;amp;  password == 'testpw'
    end
    session[:visitor] = @visitor
  else
    session[:visitor] = @visitor
  end
end

def logged_in?
  !!session[:visitor]
end
  

Почему это превращается в строку? Я использовал поиск проекта в atom, и я только когда-либо вызывал его в этих местах.

Редактировать:

Я добавил a binding.pry в 4 местах, которые я называю session[:visitor], и он работает с первого раза во всем. Как только я впервые перехожу по URL-адресу и

 before_action :authenticate, unless: :logged_in?
  

вызывается во второй раз session[:visitor] , превращается в строку

 #=> "#<Visitor:0x00000106851bd0>"
  

Ответ №1:

Из документов, http://guides.rubyonrails.org/security.html#sessions

Не храните большие объекты в сеансе. Вместо этого вы должны хранить их в базе данных и сохранять их идентификатор в сеансе. Это устранит проблемы с синхронизацией и не будет заполнять пространство для хранения сеанса (в зависимости от того, какое хранилище сеанса вы выбрали, см. Ниже). Это также будет хорошей идеей, если вы измените структуру объекта, а его старые версии все еще находятся в файлах cookie некоторых пользователей. С помощью серверных хранилищ сеансов вы можете очистить сеансы, но с клиентскими хранилищами это трудно смягчить.

Сохраните идентификатор вашего посетителя в сеансе

 session[:visitor_id] = @visitor.id
  

а затем извлекайте его по мере необходимости

 @visitor = User.find_by_id(session[:visitor_id])