Записи счетчика, созданные за последние 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
Ответы
Ответ 1
Вы можете добавить where
-condition, как это:
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
Ответ 2
Я рекомендую вам добавить область в вашу модель:
class User < ActiveRecord::Base
scope :recents, where("created_at > ?", Time.now-7.days)
end
Затем вы можете сделать
self.favorites.recents.count
Ответ 3
В Rails 4 +
Этот код кажется неработоспособным:
"created_at > ?", Time.now-7.days
Я пробовал:
scope :recent, -> { where("DATE(created_at) > ?", (Date.today).to_time - 7.days) }
Ответ 4
self.links.where("created_at > ?", Time.now-7.days).count
Ответ 5
Если вы работаете в Rails, вы можете просто использовать методы datetime ago
вместо того, чтобы делать странные вычисления по времени.
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
будет в модели соединения).
Ответ 6
Я искал записи, которые могли бы вернуться за 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)}