2010-05-03 4 views
0

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

@events = Event.find(:all) 

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

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

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

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

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

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

+0

это ActiveRecord, а не ActionRecord :) –

ответ

1

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

:conditions => ["when.wday=4"]

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

Попробуйте

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

SQLLite исх: 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... 
+0

Спасибо! Это прекрасно и чрезвычайно полезно для того, чтобы направить меня к правильной практике, когда я впервые исследую RoR. Очень признателен! – Pygmalion

+0

Последний вопрос: Должен ли этот классный метод в модели проходить в классе Events? И если да, то это должно быть «self.find_by_day»? – Pygmalion

+0

Рад помочь. Да, метод класса для модели будет в классе Event (сингулярное слово Event). То есть, файл event.rb, представляющий таблицу событий (множественное число). Для метода класса def self.find_by_day является * точно таким же, как * def Event.find_by_day, поскольку self (в этом контексте) превращается в Событие –

Смежные вопросы