Ruby-on-rails 计算过去 7 天内创建的记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8426781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:27:41  来源:igfitidea点击:

Count records created within the last 7 days

ruby-on-railsrubyruby-on-rails-3activerecord

提问by Dru

How can I alter the query below to only select records created within the last 7 days?

如何更改下面的查询以仅选择过去 7 天内创建的记录?

self.favorites.count

This function is located in my Usermodel.

此功能位于我的User模型中。

 def calculate_user_score
    unless self.new_record?
      self.score = (self.links.count * 5) + (self.favorites.count * 0.5)
    end
  end  

回答by Ben Lee

You can add a where-condition like this:

您可以where像这样添加-condition:

self.favorites.where('created_at >= ?', 1.week.ago).count

And for your calculate_user_scoremethod, you probably want to do that for linksas well:

对于您的calculate_user_score方法,您可能也想这样做links

def calculate_user_score
  unless new_record?
    self.score = (links.where('created_at >= ?', 1.week.ago).count * 5) +
      (favorites.where('created_at >= ?', 1.week.ago).count * 0.5)
  end
end  

回答by Augustin Riedinger

I recommend you add a scope to your model:

我建议您为模型添加一个范围:

class User < ActiveRecord::Base

  scope :recents, where("created_at > ?", Time.now-7.days)

end

Then you can do

然后你可以做

self.favorites.recents.count

回答by aldrien.h

In Rails 4+

Rails 中 4+

This code seems not working:

这段代码似乎不起作用:

"created_at > ?", Time.now-7.days

I tried like:

我试过:

scope :recent, -> { where("DATE(created_at) > ?", (Date.today).to_time - 7.days) }

回答by zed_0xff

self.links.where("created_at > ?", Time.now-7.days).count

回答by armahillo

If you're working in Rails, you can just use the agodatetime methods, instead of doing weird time math.

如果你在 Rails 中工作,你可以只使用agodatetime 方法,而不是做奇怪的时间数学。

scope :recent, -> { where("created_at > ?", 1.week.ago) }

In Rails, you can usually avoid a lot of the complicated data preparation and type-casting you might have to do in other languages / frameworks.

在 Rails 中,您通常可以避免在其他语言/框架中可能必须进行的许多复杂的数据准备和类型转换。

Re: the original post, I would probably refactor it like this:

回复:原帖,我可能会像这样重构它:

# Using association extensions here to filter this down,
# the ellipses parenthetical should be whatever you're using for your
# association definition.

has_many :links ( ... ) do
  def since(last_date)
    where('created_at > ?', last_date)
  end
end
has_many :favorites (...) do
  def since(last_date)
    where('created_at > ?', last_date)
  end
end

# Don't use magic numbers; codify them for context.
LINK_SCORE_MULTIPLIER = 5
FAVE_SCORE_MULTIPLIER = 0.5

# Note this does not persist it in the database; if you want it to persist 
# you'll want to execute an update instead. However it does memoize it so multiple
# calls will pull from the in-memory cache of the object instead of re-querying it
def score(recalculate: true)
  @score ||= (links.since(1.week.ago).count * LINK_SCORE_MULTIPLIER) +
            (favorites.since(1.week.ago).count * FAVE_SCORE_MULTIPLIER)
end

Then you just reference it passively:

然后你只是被动地引用它:

@user.score # runs the query and saves to memory
@user.score # pulls from memory
@user.score(recalculate: true) # re-runs the query and saves to memory
@user.save  # persists the result (assuming you have a field for :score)

It might require refactoring, but depending on how your data is modeled, you might be able to use a counter_cacheto track it (this would require a has_many,throughassociation, and the counter_cachewould be on the joining model.

它可能需要重构,但根据您的数据建模方式,您可能可以使用 acounter_cache来跟踪它(这将需要一个has_many,through关联,并且counter_cache将在连接模型上。

回答by Datt

I was looking for records which could return last 7 daysi.e. not including today. But this worked for me and it can work for last n days.

我正在寻找可以返回的记录,last 7 days即不包括今天。但这对我有用,并且可以用于last n days.

last_n_days = 7

Model.where('created_at BETWEEN ? AND ?', Date.today-last_n_days, Date.today-1).count

with scope

有范围

scope :last_n_days, lambda {|n| where('created_at BETWEEN ? AND ?', Date.today - n, Date.today - 1)}