ruby-on-rails – 计算在Rails中发布的连续天数

ruby-on-rails – 计算在Rails中发布的连续天数,第1张

概述在一个简单的 Ruby on Rails应用程序中,我正在尝试计算用户发布的连续天数.例如,如果我在过去4天中发布了每一天,我想在我的个人资料中说“你目前的帖子连续4天,继续保持!”或类似的东西. 我应该跟踪我的某个模型中的“条纹”,还是应该在其他地方计算它们?不知道我应该在哪里做,或者如何正确地做到这一点,所以任何建议都会很精彩. 我很高兴包含您认为有用的任何代码,请告诉我. 我不确定它是否是最 在一个简单的 Ruby on Rails应用程序中,我正在尝试计算用户发布的连续天数.例如,如果我在过去4天中发布了每一天,我想在我的个人资料中说“你目前的帖子连续4天,继续保持!”或类似的东西.

我应该跟踪我的某个模型中的“条纹”,还是应该在其他地方计算它们?不知道我应该在哪里做,或者如何正确地做到这一点,所以任何建议都会很精彩.

我很高兴包含您认为有用的任何代码,请告诉我.

解决方法 我不确定它是否是最好的方法,但这是在sql中实现它的一种方法.首先,看看以下查询.

SELECT  serIEs_date,COUNT(posts.ID) AS num_posts_on_dateFROM generate_serIEs(       '2014-12-01'::timestamp,'2014-12-17'::timestamp,'1 day'     ) AS serIEs_dateleft OUTER JOIN posts ON posts.created_at::date = serIEs_dateGROUP BY serIEs_dateORDER BY serIEs_date DESC;

我们使用generate_serIEs生成从2014-12-01开始到2014-12-17(今天)结束的日期范围.然后我们用posts表进行left OUTER JOIN.这为我们在范围内的每一天提供了一行,当天在num_posts_on_date列中有帖子数.结果看起来像这样(SQL Fiddle here):

serIEs_date                     | num_posts_on_date---------------------------------+------------------- December,17 2014 00:00:00+0000 |                 1 December,16 2014 00:00:00+0000 |                 1 December,15 2014 00:00:00+0000 |                 2 December,14 2014 00:00:00+0000 |                 1 December,13 2014 00:00:00+0000 |                 0 December,12 2014 00:00:00+0000 |                 0 ...                             |               ... December,01 2014 00:00:00+0000 |                 0

现在我们知道从12月14日到17日每天都有一个帖子,所以如果今天的12月17日我们知道当前的“连胜”是4天.我们可以做更多的sql来获得最长的连胜纪录,如described in this article,但由于我们只对“当前”连胜的长度感兴趣,所以只需稍作改动.我们所要做的就是更改查询以仅获取num_posts_on_date为0的第一个日期(SQL Fiddle):

SELECT serIEs_dateFROM generate_serIEs(       '2014-12-01'::timestamp,'1 day'     ) AS serIEs_dateleft OUTER JOIN posts ON posts.created_at::date = serIEs_dateGROUP BY serIEs_dateHAVING COUNT(posts.ID) = 0ORDER BY serIEs_date DESCliMIT 1;

结果如下:

serIEs_date--------------------------------- December,13 2014 00:00:00+0000

但是因为我们实际上想要从最后一天起没有帖子的天数,我们也可以在sql中做到这一点(SQL Fiddle):

SELECT ('2014-12-17'::date - serIEs_date::date) AS daysFROM generate_serIEs(       '2014-12-01'::timestamp,'1 day'     ) AS serIEs_dateleft OUTER JOIN posts ON posts.created_at::date = serIEs_dateGROUP BY serIEs_dateHAVING COUNT(posts.ID) = 0ORDER BY serIEs_date DESCliMIT 1;

结果:

days------    4

你去!

现在,如何将它应用于我们的Rails代码?像这样的东西:

qry = <<-sql  SELECT (CURRENT_DATE - serIEs_date::date) AS days  FROM generate_serIEs(         ( SELECT created_at::date FROM posts           WHERE posts.user_ID = :user_ID           ORDER BY created_at           ASC liMIT 1         ),CURRENT_DATE,'1 day'       ) AS serIEs_date  left OUTER JOIN posts ON posts.user_ID = :user_ID AND                           posts.created_at::date = serIEs_date  GROUP BY serIEs_date  HAVING COUNT(posts.ID) = 0  ORDER BY serIEs_date DESC  liMIT 1sqlPost.find_by_sql([ qry,{ user_ID: some_user.ID } ]).first.days # => 4

正如您所看到的,我们添加了一个条件来限制user_ID的结果,并用一个查询替换我们的硬编码日期,该查询获取用户的第一个帖子的日期(generate_serIEs函数内的子选择)作为范围的开头和CURRENT_DATE为范围的结尾.

最后一行有点搞笑,因为find_by_sql将返回一个Post实例数组,因此您必须在数组中的第一个上调用days来获取值.或者,您可以这样做:

sql = Post.send(:sanitize_sql,[ qry,{ user_ID: some_user.ID } ])result_value = Post.connection.select_value(sql)streak_days = Integer(result_value) rescue nil # => 4

在ActiveRecord中,它可以变得更干净:

class Post < ActiveRecord::Base  USER_STREAK_DAYS_sql = <<-sql    SELECT (CURRENT_DATE - serIEs_date::date) AS days    FROM generate_serIEs(          ( SELECT created_at::date FROM posts            WHERE posts.user_ID = :user_ID            ORDER BY created_at ASC            liMIT 1          ),'1 day'        ) AS serIEs_date    left OUTER JOIN posts ON posts.user_ID = :user_ID AND                             posts.created_at::date = serIEs_date    GROUP BY serIEs_date    HAVING COUNT(posts.ID) = 0    ORDER BY serIEs_date DESC    liMIT 1  sql  def self.user_streak_days(user_ID)    sql = sanitize_sql [ USER_STREAK_DAYS_sql,{ user_ID: user_ID } ]    result_value = connection.select_value(sql)    Integer(result_value) rescue nil  endendclass User < ActiveRecord::Base  def post_streak_days    Post.user_streak_days(self)  endend# And then...u = User.find(123)u.post_streak_days # => 4

以上是未经测试的,因此可能需要一些摆弄才能使其正常工作,但我希望它至少能指出正确的方向.

总结

以上是内存溢出为你收集整理的ruby-on-rails – 计算在Rails中发布的连续天数全部内容,希望文章能够帮你解决ruby-on-rails – 计算在Rails中发布的连续天数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1286763.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-09
下一篇2022-06-09

发表评论

登录后才能评论

评论列表(0条)

    保存