gpt4 book ai didi

ruby-on-rails - 如何在 Rails 应用程序中记录上次事件的时间?

转载 作者:行者123 更新时间:2023-12-01 09:00:18 24 4
gpt4 key购买 nike

在我的 Rails 应用程序中,我想记录 userlast_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 绕过了大部分,专注于完成将时间戳更新持久化到模型所需的工作。

关于ruby-on-rails - 如何在 Rails 应用程序中记录上次事件的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18302485/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com