Использование вспомогательных методов Rails в запросах ActionRecord? - PullRequest
0 голосов
/ 03 мая 2010

У меня есть таблица событий (в базе данных sqlite3, для которой она стоит) со столбцом «когда», который содержит метку времени, детализирующую точно, когда установлено событие, которое обозначает данная строка. Прямо сейчас у меня есть

@events = Event.find(:all)

в моем контроллере, и я использую вспомогательные методы шаблона, чтобы вычислить, где разместить каждое событие на моей странице отображения на основе дня недели, когда оно происходит. Например:

<% if(event.when.wday == 6) %>
    # DO SOMETHING
<% end %>

Однако я хочу абстрагировать эту логику для контроллера. Моя идея заключалась в том, чтобы сделать следующее:

@thursday_events = Event.find(:all, :conditions => ["when.wday=4"])

Очевидно (я думаю?) Это не сработало. Выдает ошибку "SQLite3 :: SQLException: near" when ": синтаксическая ошибка: SELECT * FROM" events "WHERE (when.wday = 4)".

Я предполагаю, что это потому, что я пытался использовать вспомогательный метод в условии поиска, но я не знаю лучшего способа сделать это. Любой совет? Спасибо!

1 Ответ

1 голос
/ 03 мая 2010

Параметр условий должен быть фрагментом SQL.

: условия => ["when.wday = 4"]

- это фрагмент кода Ruby, поэтому не стоит.

Попробуйте

# Model Event has a datetime field named 'when'
Event.find(:all, :conditions => ["strftime('%w', events.when) = 4"])

SQLLite ref: http://www.sqlite.org/lang_datefunc.html

Добавлено:

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

Каждый запрос имеет значительные накладные расходы. Например:

#Do NOT do it this way (too many db queries)
@sunday_events = Event.find(:all, 
   :conditions => ["strftime('%w', events.when) = 0"])
@monday_events = Event.find(:all, 
   :conditions => ["strftime('%w', events.when) = 1"])
@thursday_events = Event.find(:all, 
   :conditions => ["strftime('%w', events.when) = 4"])
# ... etc

# Better: Just 1 database query--
events = Event.find(:all)
@sunday_events   = events.select{|e| e.when.wday == 0}
@monday_events   = events.select{|e| e.when.wday == 1}
@thursday_events = events.select{|e| e.when.wday == 4} 
# ... etc

Окончательный комментарий:

В настоящее время передовой практический подход заключается в переносе кода в модели с контроллеров, где это целесообразно. Это называется «Толстая модель, тощий контроллер». В приведенном выше примере вы можете использовать метод уровня класса , в модели создать отдельные переменные экземпляра. Или, может быть, лучше, один хеш, который содержит 7 значений, каждое из которых представляет собой массив записей. Например,

# in Event model
def Event.find_by_day
  events = Event.find(:all)
  result = {}
  days = [:sun, :mon, :tue, :wed, :thu, :fri, :sat]
  (0..6).each{|day_i| result[days[day_i]] = 
                        events.select{|e| e.when.wday == day_i}
              }

  result
end

# in controller
@events = Event.find_by_day

# in view
# @events[:sun] is array of the Sunday events
#   so do something with them...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...