Я бы, наверное, сделал что-то вроде этого:
Награда класса также должна иметь столбец award_at, в котором указана дата присуждения премии. Поэтому, когда пришло время создать награду, это можно сделать так:
# This will make sure that no award will be created if it already exists for the current date
@user.awards.find_or_create_by_prize_id_and_awarded_at(@prize.id, Time.now.strftime("%Y-%m-%d"))
И тогда у нас будет возможность загрузить всех пользователей премией, срок действия которой истекает сегодня, и никаких активных наград за предоставленный приз.
# user.rb
scope :are_losing_award, lambda { |prize_id, expires_after|
joins("INNER JOIN awards AS expired_awards ON users.id = expired_awards.user_id AND expired_awards.awarded_at = '#{(Time.now - expires_after.days).strftime("%Y-%m-%d")}'
LEFT OUTER JOIN awards AS active_awards ON users.id = active_awards.user_id AND active_awards.awarded_at > '(Time.now - expires_after.days).strftime("%Y-%m-%d")}' AND active_awards.prize_id = #{prize_id}").
where("expired_awards.prize_id = ? AND active_awards.id IS NULL", prize_id)
}
Итак, мы можем назвать это так:
# Give me all users who got the prize three days ago and has not gotten it again since
User.are_losing_award(@prize.id, 3)
Могут быть некоторые способы лучше написать область с запросами ARel или что-то в этом роде, я пока не эксперт, но этот способ должен работать до тех пор:)