[英]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.