【问题标题】:Using Rails Helper Methods within ActionRecord Queries?在 ActionRecord 查询中使用 Rails Helper 方法?
【发布时间】:2010-05-03 12:14:26
【问题描述】:

我有一个事件表(在 sqlite3 数据库中),其中包含一个名为“when”的列,其中包含一个时间戳,详细说明了特定行表示的事件何时发生。现在,我有

@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": syntax error: SELECT * FROM "events" WHERE (when.wday=4)"。

我假设这是因为我尝试在查找条件中使用辅助方法,但我不知道更好的方法来做到这一点。有什么建议吗?谢谢!

【问题讨论】:

  • 它是 ActiveRecord,而不是 ActionRecord :)

标签: ruby-on-rails ruby activerecord


【解决方案1】:

条件参数需要是一段SQL。

:条件 => ["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...

【讨论】:

  • 谢谢!当我第一次探索 RoR 时,这对指导我进行正确的实践非常有帮助。非常感谢!
  • 最后一个问题:模型中的类级方法是否应该放在 Events 类中?如果是这样,它应该是“self.find_by_day”吗?
  • 很高兴能提供帮助。是的,模型的类级方法将在 Event 类中(单数 Event)。即 event.rb 文件,代表 events(复数)表。对于类方法,def self.find_by_day 与 def Event.find_by_day 完全相同,因为 self(在此上下文中)变成了 Event
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多