または、テーブルを完全に回避しVote
て、外部の集計を維持することもできます。
投票が行われるたびに、現在の投票数を保持する別の集計クラスが呼び出されます。集計レコードは 1 日 1 件になります。集計レコードには、その日に投じられた投票数を表す整数が含まれます。
集計クラスへの増分呼び出しごとに、現在の日付 (今日) の集計レコードが検索され、投票数が増分され、レコードが保存されます。レコードが存在しない場合は、レコードが作成され、それに応じて増分されます。
たとえばVoteTally
、日付 (日付) と投票数 (整数) の 2 つの属性、タイムスタンプなし、関連付けなしで呼び出されるクラスがあるとします。モデルは次のようになります。
class VoteTally < ActiveRecord::Base
def self.tally_up!
find_or_create_by_date(Date.today).increment!(:votes)
end
def self.tally_down!
find_or_create_by_date(Date.today).decrement!(:votes)
end
def self.votes_on(date)
find_by_date(date).votes
end
end
次に、Vote
モデルで:
class Vote < ActiveRecord::Base
after_create :tally_up
after_destroy :tally_down
# ...
private
def tally_up ; VoteTally.tally_up! ; end
def tally_down ; VoteTally.tally_down! ; end
end
これらのメソッドは投票数を取得します:
VoteTally.votes_on Date.today
VoteTally.votes_on Date.yesterday
VoteTally.votes_on 3.days.ago
VoteTally.votes_on Date.parse("5/28/13")
もちろん、これは単純な例であり、それに合わせて調整する必要があります。これにより、投票中に追加のクエリが発生しますが、where
インデックスのない 1 億レコードの句よりもはるかに高速です。この解決策では多少の不正確さが生じる可能性がありますが、毎日の投票数の逸話的な性質を考えると、それは許容できると思います。