我有一个事件表(在一个sqlite3数据库中,它的价值),一个名为“when”的列,其中包含一个时间戳,详细说明特定行表示的事件是否设置为何时发生。现在,我有
@events = Event.find(:all)
在我的控制器中,我正在使用模板帮助程序方法来计算将每个事件放在显示页面上的位置,具体取决于它发生的星期几。例如:
<% if(event.when.wday == 6) %>
# DO SOMETHING
<% end %>
我想将此逻辑抽象给控制器。我的想法是做以下事情:
@thursday_events = Event.find(:all, :conditions => ["when.wday=4"])
显然(我猜?)这没用。当“:语法错误:SELECT * FROM”事件“WHERE(when.wday = 4)”时抛出错误“SQLite3 :: SQLException:near”。
我假设这是因为我试图在查找条件中使用辅助方法,但我不知道更好的方法。有什么建议?谢谢!
答案 0 :(得分:1)
conditions参数必须是SQL的一个片段。
:conditions =&gt; [ “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...