重构和改进Rails中的查询

时间:2012-04-27 10:58:36

标签: ruby-on-rails performance postgresql caching

Outlet.rb

def latest_reports
  weekly_reports.limit(10)
end

Outlet_controller.rb

@all_outlets = Outlet.includes(:weekly_reports)
@search = @all_outlets.search(params[:q])   # load all matching records
@outlets = @search.result.order("created_at DESC").page(params[:page])

出口/ index.slim

- @outlets.each do |outlet|
  tr
    td= link_to outlet.name, outlet_path(outlet)
    th
      ul.reports
        li class="#{'done' if outlet.monitored_today}"
    th
      ul.reports
        - for report in outlet.latest_reports
          li class="#{'done' if report.quota_met}"= report.times_monitored

我不确定为什么,但这会将其加载为几个不同的查询。我很确定这是因为我的控制器中的include不正确(因为我在模型中使用了一个方法)。

如果有人能帮助我改进这一点,我将非常感激:)。

注意:我正在开发PostgreSQL

更新::发布了完整的控制器操作。

1 个答案:

答案 0 :(得分:2)

至少在rails 3中,如果你使用

Model1.includes :model2

然后结果是每个模型一个查询。您可以从结果中访问关联模型的实例,不会进行额外的查询。

如果您真的想在一个查询中完成所有操作,则可以执行以下操作:

Model1.joins(:model2).includes(model2)

这将生成一个很好的长JOIN查询,一次加载两个模型的所有数据。 Rails将使用已加载的两个模型的实例填充结果。

所以,你应该可以替换

@all_outlets = Outlet.includes(:weekly_reports)

@all_outlets = Outlet.includes(:weekly_reports).joins(:weekly_reports)

它应该将所有内容组合成一个查询。