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