web-dev-qa-db-ja.com

過去7日以内に作成されたレコードをカウントします

以下のクエリを変更して、過去7日以内に作成されたレコードのみを選択するにはどうすればよいですか?

self.favorites.count

この関数は私のUserモデルにあります。

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

次のようにwhere-条件を追加できます。

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

そしてあなたのために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  
49
Ben Lee

モデルにスコープを追加することをお勧めします。

class User < ActiveRecord::Base

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

end

その後、あなたはすることができます

self.favorites.recents.count
13

Rails 4 +

このコードは機能していないようです:

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

私は次のように試しました:

scope :recent, -> { where("DATE(created_at) > ?", (Date.today).to_time - 7.days) }
7
aldrien.h
self.links.where("created_at > ?", Time.now-7.days).count
1
zed_0xff

Railsで作業している場合は、奇妙な時間計算を行う代わりに、agodatetimeメソッドを使用できます。

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

Railsでは、通常、他の言語/フレームワークで行う必要のある複雑なデータ準備と型キャストの多くを回避できます。

Re:元の投稿、おそらく次のようにリファクタリングします:

# 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

次に、それを受動的に参照します。

@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)

リファクタリングが必要になる場合がありますが、データのモデル化方法によっては、counter_cacheを使用してデータを追跡できる場合があります(これにはhas_manythroughの関連付けが必要であり、 counter_cacheは結合モデルになります。

0
armahillo

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

スコープ付き

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