Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在Rails应用程序中记录上次活动的时间?_Ruby On Rails_Ruby On Rails 3_Ruby On Rails 3.2 - Fatal编程技术网

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

Ruby on rails 如何在Rails应用程序中记录上次活动的时间?,ruby-on-rails,ruby-on-rails-3,ruby-on-rails-3.2,Ruby On Rails,Ruby On Rails 3,Ruby On Rails 3.2,在我的Rails应用程序中,我想记录用户上次出现的时间 现在,我在我的会话助手中执行以下操作: def sign_in(user) ..... user.update_column(:last_seen, Time.zone.now) self.current_user = user end 但这并不十分精确,因为用户可能在上午8点登录,而在晚上,last\u seen数据库列仍将包含该时间 因此,每当用户采取行动时,我就想更新上次看到的: class ApplicationCon

在我的Rails应用程序中,我想记录
用户上次出现的时间

现在,我在我的
会话助手中执行以下操作:

def sign_in(user)
  .....
  user.update_column(:last_seen, Time.zone.now)
  self.current_user = user
end
但这并不十分精确,因为用户可能在上午8点登录,而在晚上,
last\u 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实际上通过
触摸内置了这种行为:

User.last.touch
#=> User's updated_at is updated to the current time
在任何配置良好的数据库中,处理像这样的单个列的更新所需的时间应该小于5ms,很可能小于1ms。如果您已经要建立数据库连接(或者,在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
def touch(name=nil)
属性=模型中更新的时间戳属性
属性self[primary_key]}=1
结束
结束
现在你告诉我,哪个更快?哪个更正确

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

“但仅仅因为其他人使用它并不能使它在经验上更好,”你争辩道。当然,你是对的,但它又一次漏掉了重点:虽然你可以继续构建你的应用程序,制作其他人(你的用户)可以使用并从中受益的东西,但你在这里旋转你的轮子,想知道什么对机器更有利,即使其他人已经找到了一个好的解决方案


是的,你的代码要慢一些。它执行回调,执行脏跟踪,并将所有更改的属性保存到数据库中
touch
忽略了大部分内容,专注于准确完成将时间戳更新持久化到您的模型所需的工作。

好的,很好。我不知道。但在文档中,它指出,
touch
会更新数据库中的
updated_at
字段。如果我想更新另一个字段,比如上次看到的
字段,该怎么办?我在上面发布的代码会比触摸法慢吗?我假设这两种方法都会以某种方式影响数据库。@Tintin81您应该仔细查看该文档。好吧,好吧,你赢了;-)我想是你让我爱上了触摸。谢谢你的帮助和精彩的评论。