Подтвердить что ты не робот

Записи счетчика, созданные за последние 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  
4b9b3361

Ответ 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)}