以下のクエリを変更して、過去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
次のように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
モデルにスコープを追加することをお勧めします。
class User < ActiveRecord::Base
scope :recents, where("created_at > ?", Time.now-7.days)
end
その後、あなたはすることができます
self.favorites.recents.count
でRails 4 +
このコードは機能していないようです:
"created_at > ?", Time.now-7.days
私は次のように試しました:
scope :recent, -> { where("DATE(created_at) > ?", (Date.today).to_time - 7.days) }
self.links.where("created_at > ?", Time.now-7.days).count
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
は結合モデルになります。
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)}