Подсчет записей, созданных за последние 7 дней - PullRequest
23 голосов
/ 08 декабря 2011

Как изменить запрос ниже, чтобы выбрать только записи, созданные за последние 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  

Ответы [ 6 ]

46 голосов
/ 08 декабря 2011

Вы можете добавить условие 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  
11 голосов
/ 02 апреля 2014

Рекомендую добавить область для вашей модели:

class User < ActiveRecord::Base

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

end

Тогда вы можете сделать

self.favorites.recents.count
7 голосов
/ 27 апреля 2016

In Рельсы 4 +

Этот код не работает:

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

Я пробовал как:

scope :recent, -> { where("DATE(created_at) > ?", (Date.today).to_time - 7.days) }
1 голос
/ 08 декабря 2011
self.links.where("created_at > ?", Time.now-7.days).count
0 голосов
/ 02 июля 2019

Я искал записи, которые могли бы вернуть 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 голосов
/ 11 марта 2019

Если вы работаете в Rails, вы можете просто использовать ago методы datetime, вместо того, чтобы делать странные вычисления по времени.

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_many, through, а counter_cache будет в модели присоединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...