繁体   English   中英

如何在Rails应用程序中记录上次活动的时间?

[英]How to record time of last activity in Rails app?

在我的Rails应用程序中,我想记录user last_seen的时间。

现在,我在SessionsHelper

def sign_in(user)
  .....
  user.update_column(:last_seen, Time.zone.now)
  self.current_user = user
end

但这不是很精确,因为用户可能会在上午8点登录,而在晚上, last_seen数据库列仍将包含该时间。

所以我想在用户采取行动时更新last_seen

class ApplicationController
  before_filter :update_last_seen

  private

  def update_last_seen
    current_user.last_seen = Time.zone.now
    current_user.save
  end
end

但我不喜欢这种方法,因为数据库会因用户采取的每个操作而受到攻击。

那么什么可能是一个更好的替代品呢?

Rails实际上有touch内置的这种行为:

User.last.touch
#=> User's updated_at is updated to the current time

任何设备齐全的数据库处理像这样更新单个列所花费的时间应该远低于5毫秒,很可能在1毫秒之内。 如果您已经要建立该数据库连接(或者在Rails的情况下,使用先前从池中建立的连接),则开销可以忽略不计。


要回答关于代码是否较慢的问题,那么你正在考虑这个问题。 您可以针对性能优化已经非常快速的操作,但我更担心“正确性”。 以下是ActiveRecord touch方法的实现:

def touch(name = nil)
  attributes = timestamp_attributes_for_update_in_model
  attributes << name if name

  unless attributes.empty?
    current_time = current_time_from_proper_timezone
    changes = {}

    attributes.each do |column|
      changes[column.to_s] = write_attribute(column.to_s, current_time)
    end

    changes[self.class.locking_column] = increment_lock if locking_enabled?

    @changed_attributes.except!(*changes.keys)
    primary_key = self.class.primary_key
    self.class.unscoped.update_all(changes, { primary_key => self[primary_key] }) == 1
  end
end

现在你告诉我,哪个更快 哪个更正确

在这里,我将给你一个提示:成千上万的人已经使用了这种touch实现,这个代码可能已经运行了数百万次。 您的代码已被您单独使用,可能甚至没有编写测试,也没有任何同行评审。

“但仅仅因为其他人使用它并不能让它在经验上更好,”你争辩道。 当然,你是对的,但是它再次忽略了这一点:虽然你可以继续构建你的应用程序并制作其他人类(你的用户)可以使用和受益的东西,但是你在旋转你的车轮想知道什么是更好的尽管其他人已经找到了一个好的解决方案。

为了在棺材里钉一把,是的,你的代码速度较慢。 它执行回调,执行脏跟踪,并将所有已更改的属性保存到数据库。 touch绕过了大部分内容,专注于完成保持时间戳更新到模型所需的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM