Подтвердить что ты не робот

Rails: как показать пользователю "последний раз видели"?

Я использую программу, которая хранит current_sign_in_at и last_sign_in_at datetimes.

Но скажем, что пользователь зарегистрировался месяц назад, но последний раз просматривал страницу 5 минут назад?

Есть ли способ показать это ("Пользователь последний раз видел 5 минут назад" ).

4b9b3361

Ответ 1

Как насчет этого:

  • Создайте миграцию, чтобы добавить новое поле для пользователей, чтобы сохранить дату и время последнего посещения пользователя:

    rails g migration add_last_seen_at_to_users last_seen_at:datetime
    
  • Добавьте обратный вызов до действия вашего контроллера приложения:

    before_action :set_last_seen_at, if: proc { user_signed_in? }
    
    private
    def set_last_seen_at
      current_user.update_attribute(:last_seen_at, Time.current)
    end
    

Таким образом, при каждом запросе (т.е. активности), который выполняет текущий пользователь, его/ее последний вид в атрибуте обновляется до текущего времени.

Обратите внимание, однако, что это может занять некоторые из ваших ресурсов приложения, если у вас много пользователей, которые вошли в систему, потому что это будет выполняться перед каждым действием контроллера, запрошенным кем-то, кто вошел в систему.

Если производительность вызывает беспокойство, подумайте о добавлении к шагу 2 следующего механизма дроссельной заслонки (в этом примере дросселирование через 15 минут):

before_action :set_last_seen_at, if: proc { user_signed_in? && (session[:last_seen_at] == nil || session[:last_seen_at] < 15.minutes.ago) }

private
def set_last_seen_at
  current_user.update_attribute(:last_seen_at, Time.current)
  session[:last_seen_at] = Time.current
end

Ответ 2

Чтобы повысить производительность предыдущего ответа:

  • не использовать сеанс, так как пользователь уже загружен надзирателем и доступны все атрибуты
  • update_attribute запускает обратные вызовы и обновления updated_at, а update_column not
  • для повышения производительности, лучше использовать фоновых работников, таких как ActiveJob/Resque/Sidekiq
  • чтобы предотвратить высокую блокировку БД, лучше создать отдельную таблицу, связанную с таблицей пользователей, и написать туда доступ.

Обновленный код:

before_action :set_last_seen_at, if: proc { user_signed_in? && (user.last_seen_at.nil? || user.last_seen_at < 15.minutes.ago) }

private
def set_last_seen_at
  current_user.update_column(:last_seen_at, Time.now)
end

Разработчик плагинов делает подобное поведение (только последний раз видел, без оптимизации): https://github.com/ctide/devise_lastseenable