Rails 3: Возможно ли получить доступ к атрибуту модели в запросе?

#ruby-on-rails #ruby-on-rails-3

#ruby-on-rails #ruby-on-rails-3

Вопрос:

Извините, если этот вопрос звучит странно, но я погружаюсь в Rails и все еще изучаю жаргон. По сути, я пытаюсь создать однопроходный запрос, который использует значение одного из атрибутов модели при вычислении в запросе (предполагая, что это вообще возможно).

У меня есть Tournament модель, у которой есть start_date атрибут, который является DateTime объектом. Я пытаюсь создать запрос, который возвращает все турниры, у которых start_date не старше 1 часа продолжительность турнира, или, другими словами, все турниры, которые еще не начались или уже начались, но закончились не более часа назад. Мой текущий запрос, который не работает, выглядит следующим образом…

 validTourneys = Tournament.where("start_date > (? - duration_in_mins)", (DateTime.now.utc - 1.hour))
  

где duration_in_mins — целочисленный атрибут модели турнира, но этот запрос не работает, и, похоже, он постоянно возвращает все турниры. Я хотел бы включить его duration_in_mins в (DateTime.now.utc - 1.hour) часть вычисления, но я не знаю, как ссылаться на него, поэтому я включил его в строковую часть запроса, надеясь, что это сработает. По крайней мере, я на правильном пути?

Я должен упомянуть, что я использую SQLite для разработки и PostgreSQL для производства.

Спасибо за вашу мудрость!

Ответ №1:

Проблема в том, что если вы вычитаете минуты из объекта DateTime, вы вычитаете не минуты, а дни.

 # This works as expected
dt = DateTime.now # Thu, 28 Apr 2011 09:55:14  0900
an_hour_ago = dt - 1.hour  # Thu, 28 Apr 2011 08:55:14  0900

# But, this does not...
two_hours_in_minutes = 120
two_hours_ago = dt - two_hours_in_minutes # Wed, 29 Dec 2010 09:55:14  0900
  

В последнем примере вместо минут вычитается 120 дней. Вероятно, это также происходит в вашем запросе. Вы должны преобразовать duration_in_minutes в дни, а затем вычесть.

Ответ №2:

Я недостаточно разбираюсь в SQL, чтобы ответить на ваш вопрос напрямую (я думаю, это, вероятно, также будет зависеть от того, какую базу данных вы используете, поэтому вы можете захотеть упомянуть об этом).

Однако рассматривали ли вы возможность использования start_date и end_date в качестве столбцов даты и времени вместо start_date и duration_in_mins ? Если это будет обычный запрос, это, безусловно, повысит его производительность, а также облегчит чтение и понимание вашего кода.

Ответ №3:

Этот запрос будет работать, только если ваша база данных достаточно умна, чтобы знать, как добавить (что я предполагаю), это DateTime и и целое число. И я не могу придумать базу данных, которая будет делать это правильно так, как вы ее закодировали. Ни одна база данных не будет занимать минуты. Некоторые могут занимать такты, секунды или дни.

Эта часть вычисления

 (? - duration_in_mins)
  

это произойдет в базе данных, а не в Ruby-land.