Запрос Rails: сравните вычисление двух значений атрибута
У меня есть модель, продукт, который имеет как :created_at
отметка времени и :expiration_in_days
приписывать. Продукты считаются просроченными через определенное количество дней после их создания. Как мне написать запрос, который возвращает только товары, срок годности которых не истек?
Rails 4, Ruby 2.1, PG 0.17
Я пробовал подобные запросы, но безуспешно:
#product.rb
def self.not_expired
where('created_at + expiration_in_days * 86400 >= ?', Time.now)
end
У меня есть чистая версия Ruby, которая работает нормально, она только медленнее:
#product.rb
def self.not_expired
select{ |p| (p.created_at.to_i + p.expiration_in_days * 86400) >= Time.now.to_i}
end
- обратите внимание, что вычисление 86400 преобразует целое число:expiration_in_days в секунды
Любые указатели на более продвинутые запросы Rails, чем документация ( http://guides.rubyonrails.org/active_record_querying.html), также будут приветствоваться.
Заранее спасибо.
3 ответа
Попробуй это:
def self.not_expired
where("created_at + (expiration_in_days * 86400)::text::interval >= ?", Time.now)
end
ОБНОВЛЕНИЕ: Добавить ссылки
Вы можете узнать больше о функции даты и времени здесь.
Учитывая ваш случай имеет особое требование, которое является значением expiration_in_days
столбец в таблице, мы не можем использовать created_at + interval expiration_in_days day
, Вместо этого нам нужно набрать приведение его значения к interval
, Но вы не можете набирать приведение прямо к целому числу, поэтому мы приводим его к text
первый.
Я не уверен, что это сработает, но попробуйте что-то вроде этого
def self.not_expired
where("TIMESTAMP created_at + INTERVAL '1 day' * expiration_in_days >= NOW()")
end
A + B > C истинно, если A <= C - B
Таким образом, вместо того, чтобы пытаться добавить время истечения в созданный_кат, вычтите время истечения из Time.now.
def expiration_threshold
Time.now - amount_of_time # I'm not sure what type to use
end
def self.not_expired
where( "created_at > ? ", expiration_threshold )
end
Я всегда был немного озадачен тем, какой тип Rails/Ruby понадобится при работе с различными датами / временем, вам, возможно, придется поиграть.