ruby-on-rails - 计算不间断天数的最佳方法

标签 ruby-on-rails ruby activerecord

在我的应用程序中,用户有很多手势。计算用户完成手势的后续天数的好方法是什么?

现在我正在按照下面的方式进行操作,并且它按我想要的方式工作。但显然它无法扩展。

class User < ActiveRecord::Base

  # ...

  def calculate_current_streak
    return 0 unless yesterday = gestures.done_on_day(Date.today-1)
    i = 0
    while gesture = self.gestures.done_on_day(Date.today - (i+1).days).first
      i += 1
    end
    i += 1 if gestures.done_on_day(Date.today).first
    i
  end

end 

谢谢!特别指出那些可以以仅跟踪工作日的方式工作的人:)

最佳答案

这样想:

连续的长度等于自上次(工作)日用户完全不使用手势以来经过的(工作)天数,对吧?

因此,解决方案归结为计算用户未做出手势的最近一天。

为了最轻松地做到这一点,许多数据库管理员使用了一个技巧:他们使用所有 日期(例如,从 2000 年到 2100 年的所有日期)创建数据库表。该表需要只有日期字段,但您可以放入一个 bool 字段来标记非工作日,例如周末和假期。这样的表在大量查询中可以派上用场,而且您只需创建并填充一次。 (Here's 一篇关于此类表的更详细的文章,为 MS SQL 编写,但无论如何都很有见地。)

有了这个表(我们称它为 dates),您可以使用类似(伪 SQL)的方法来计算您的 pre-streak 日期:

SELECT d.date
FROM dates d
LEFT JOIN gestures g ON d.date = g.date AND g.user_id = <put_user_id_here>
WHERE d.date < TODAY() AND g.date IS NULL AND d.work_day = TRUE
ORDER BY d.date DESC
LIMIT 1

关于ruby-on-rails - 计算不间断天数的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5470665/

相关文章:

ruby-on-rails - 将 API 响应的属性/属性与本地 stub 进行比较

ruby - 这个语法叫什么? { |n| "user#{n}"}

sql - Rails + PostgreSQL SSL 解密失败

ruby-on-rails - 如何为通过 Active Storage 上传的 S3 文件设置缓存控制?

ruby-on-rails - 如何延长 activerecord 和 tinytds 超时?

ruby-on-rails - 亚马逊 ElasticBeanstalk : configure environment variable with newlines

ruby-on-rails - Ruby on Rails 是否有 "canvas_tag"功能?

jquery - 我可以在 Rails View 中指定 css::before 选择器样式吗?

ruby-on-rails - has_one 是否没有提供 `create_child` 方法?

php - Codeigniter DB Query with where, or, and.. and like