【问题标题】:"Who's Online" using Devise in Rails在 Rails 中使用 Devise 的“谁在线”
【发布时间】:2011-07-27 02:57:51
【问题描述】:

使用 Devise on Rails,有没有办法列出所有当前有活动会话的用户,即当前登录的用户?

附言。我正在寻找一个强大的解决方案,而不是像this question 中的那些简单化的解决方案

【问题讨论】:

标签: ruby-on-rails-3 devise


【解决方案1】:

https://github.com/ctide/devise_lastseenable

您可以使用我编写的这个 gem 来存储用户的“last_seen”时间戳。从那里,显示最近 5 或 10 分钟内最后一次看到的用户非常简单。

【讨论】:

  • 您能否给出显示在过去 5 或 10 分钟内最后一次看到的用户的代码。 ?
  • User.where('last_seen > ?', 5.minutes.ago)
【解决方案2】:

只需在ApplicationController中添加after_filter

after_filter :user_activity

private

def user_activity
  current_user.try :touch
end

然后在用户模型中添加在线?方法

def online?
  updated_at > 10.minutes.ago
end

你也可以创建范围

scope :online, lambda{ where("updated_at > ?", 10.minutes.ago) }

【讨论】:

  • devise_lastseenable 是否仍然适用于 rails 3.2 和 Devise 2.0?
  • @Rubytastic 我不知道,但这个解决方案非常简单,我宁愿使用它也不愿添加额外的依赖项,这可能会在以后的 rails 或 devise 版本中中断。
  • 这不是要对每个操作都运行 SQL 吗?
  • 这是一个很好的建议。因为 touch 设置了 updated_at 列,如果您使用通用列 updated_at 来查看谁在线,它可能会产生误报。例如,调整某人的用户资料会错误地将他们显示为在线 10 分钟。我们使用 current_user.try(:touch, :last_response_at) 并通过迁移将这个新字段添加到数据库中。我们还在 session#destroy 上将其设置为 nil,以便用户在明确注销时退出。最后但同样重要的是,我们确保为新字段添加索引。
  • 我喜欢这个解决方案,但我对实现它有点困惑。如果我试图确定 current_user 是否在线(比如他们有多个选项卡并在其中一个上注销),有没有办法在不刷新页面的情况下使用它?
【解决方案3】:

我刚刚实现了另一个版本,我想分享一下,以防它帮助其他人。

我只是在我的 Users 表中添加一个 last_sign_out_at 列,然后对 Devise 会话控制器进行子类化,这样我就可以在会话被销毁(用户注销)时重写 destroy 方法来设置它:

# app/controllers

class SessionsController < Devise::SessionsController

  def destroy
    current_user.update_attribute(:last_sign_out_at, Time.now)
    super
  end

end

然后在我的用户模型中,我有一个方法来检查用户是否在线:

class User < ActiveRecord::Base

  def online?
    if current_sign_in_at.present? 
      last_sign_out_at.present? ? current_sign_in_at > last_sign_out_at : true
    else
      false
    end
  end

end

你还需要告诉 Devise 在你的路由中使用新的 Sessions 控制器。

【讨论】:

  • 这不是一个很好的解决方案(至少不是单独的),因为大多数用户不会退出,只需关闭浏览器或离开网站。
【解决方案4】:

我们可以使用活动记录会话存储列出当前活动会话。请查看github应用页面https://github.com/mohanraj-ramanujam/online-users

【讨论】:

  • 也许你可以提供一些文件?
【解决方案5】:

如果您对每次访问数据库感到困扰。单身的。 http。要求。只是有一些小窗口,您可以在其中假设用户在线;我有一个替代解决方案。

使用 websockets 和 redis 可以可靠地获取高达毫秒的用户在线状态,而无需进行 10 亿次昂贵的磁盘写入。不幸的是,它需要更多的工作并且有两个额外的依赖项,但是如果有人感兴趣,我在这里做了一个非常详细的写:

How do I tell if a user is online?

【讨论】:

  • 可以包裹成gem吗?
  • 谢谢!我在 15 分钟内完成了设置,效果很好!
  • Ryan,你的博文很棒,但你能在这里简明扼要地总结一下,这样如果你的博客/链接死了,你的方法就不会永远丢失吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多