是否有更好的方法每天记录属性的值?

时间:2015-07-30 22:09:04

标签: ruby-on-rails ruby performance cron

我的模型Thing的属性rating会随时间而变化。我希望能够查看任何Thing.rating在给定日期的价值。

例如,如果{2015年1月13日@thing = Thing.first@thing.rating等于5,我希望能够在将来的某个日期返回该值。

我的一个想法是创建一个名为ThingPast的新模型,该模型属于Thing,而Thing将具有_ {1}} ThingPastThingPast具有thing_idratingdate_created属性。每天某个时间,Cron作业会为每个ThingPast创建Thing,只需复制rating属性。

我认为这在技术上可行,但似乎不必要的复杂和低效。有谁知道更好,更简单的方法来实现这个目标?

2 个答案:

答案 0 :(得分:2)

  • 添加ratings表格,其中包含ratingthing_idcreated_at列,以及thing_idcreated_at上的索引。
  • rating移除Thing字段,并将其替换为

    has_many :ratings, order: 'created_at desc'
    
  • 将每个新的或更改的评分保存为ratings表格中的新记录,例如after_save回调。

  • 将方法添加到Thing,如:

    def rating_at(rating_time)
      ratings.where("created_at <= ?", rating_time).first.try(:rating)
    end
    
  • 并替换丢失的字段:

    def rating
      ratings.first.try(:rating)
    end
    

现在,如果您想要每日评分,您可以迭代日期并为每个评分rating_at

    (1..10).map { |days_ago| thing.rating_at(days_ago.days.ago) }.sort

不需要cron工作。

答案 1 :(得分:1)

您可以使用paper_trail gem https://github.com/airblade/paper_trail;它保留了您的模型的版本。它存储了您在versions表中选择的所有模型版本,并且与模型具有多态关系。

您可以通过查询版本表

获取所需的每日版本
PaperTrail::Version.where(item: Thing.first, created_at: Date.yesterday)

将在那个日期为您提供模型版本