控制器中的预排序关联:如何以及是否有性能增益



我有一个通过@regions循环的视图。对于每个地区,显示其国家/地区。

<% region.countries.each do |country| %>

一个新的要求是按某些列对国家进行排序,我有一个范围。

<% region.countries.order_alphabetically.each do |country| %>

但是我听说在视图中编写逻辑会严重影响性能。在这种情况下是这样吗?是否有可能在控制器中对其进行预排序?

注:我不想使用default_scope,因为我需要在其他视图中对它进行不同的排序。

编辑:更改标题以更好地反映我的问题

是否更快可能取决于表中有多少条记录以及是否对该列进行索引。您可以尝试通过以下方式将此负载传递到数据库:

region.countries.order(:column_name)

在大多数情况下,这应该比将所有记录加载到Ruby中并进行排序更快。

如果在视图的3个不同的位置放置

region.countries.order(:column_name)

这将访问数据库3次。有些人还会说,你让视图做得太多了。您可以通过

处理这两个问题
@sorted_countries = region.countries.order(:column_name)

您保留了如何从视图中排序的细节,并且通过重用相同的关系,活动记录将在重用之间缓存排序数组。

如果你只在一个地方使用已排序的国家,那么应该没有任何区别,尽管像这样将其分开可能会更容易编写测试国家正在排序的规范,并使你不太可能意外地陷入上面详细介绍的性能陷阱

很抱歉回复晚了。我想看到一些证据,所以我终于抽出时间坐下来写了一个对两者的基准比较:视图排序和控制器演示。

在页面上有许多地区,每个地区有许多国家。该页面显示所有这些国家,并按每个地区的名称对国家进行排序。运行rake test:benchmark,结果将保存在tmp/performance文件夹中。两者的结果是相同的,在0.0035左右每页渲染。

总之,在视图中调用排序作用域与在控制器中调用排序作用域在性能上没有区别。

最新更新