В исходной области видимости и решении amitamb есть скрытая ошибка.scope
- это метод класса, так почему вы говорите так:
scope :blahblah, arguments
выражение arguments
вычисляется во время анализа и загрузки класса.В частности, DateTime.now.year
будет оцениваться, когда класс загружается в среду Rails.Следовательно, если класс загружен 2012-12-31, то where
будет:
where('days.year_id != 2012')
, и если вы используете область спустя несколько часов 2013-01-01, он будетпо-прежнему использовать 2012 год как год.Есть два решения этой проблемы:
Используйте метод класса или лямбду для области:
scope :archived, -> { joins(:day).where('days.year_id != ?', DateTime.now.year) }
# or
def self.archived
joins(:day).where('days.year_id != ?', DateTime.now.year)
end
Нажмите расчет текущего годавниз в базу данных:
scope :archived, joins(:day).where('days.year_id != extract(year from current_date)')
Некоторые базы данных захотят что-то вместо extract(year from current_date)
, поэтому вы можете использовать (1) , чтобы избежать возможногопроблемы переносимости и часового пояса.
Кроме того, ваш оригинальный подход испытывает аналогичные проблемы с частью Day.where(...)
, этот запрос выполняется во время загрузки вашего класса, поэтому, если таблица days
изменяется во время работы вашего приложения,тогда вы будете проверять неправильный список.