1

希望是一个关于 Rails 最佳实践的简单问题。

让我们保持这个超级简单;假设我有一个具有 ID、描述和状态的任务模型。

在我的控制器中,我有一个返回所有任务的索引操作

def index
  @tasks = Task.all
end

我的问题是,在我看来,假设我想根据任务的状态在单独的HTML 表格中显示任务。

最佳做法是什么?

a) 在索引动作中多次查询数据库,即

def index
  @draft_tasks = Task.where(status: "Draft")
  @approved_tasks = Task.where(status: "Approved")
  @closed_tasks = Task.where(status: "Closed")
end

b) 查询数据库一次,在控制器动作中过滤

def index
  tasks = Task.all
  @draft_tasks = tasks.#somethinghere
  @approved_tasks = tasks.#somethinghere
  @closed_tasks = tasks.#somethinghere
end

c) 在视图中过滤

<% @tasks.each do |k, v| %>
  <% some if statement searching for the status I want %>
    # Some code to output the table
  <%end%>
<%end%>

或者

d) 别的?

4

4 回答 4

3

这里普遍接受的最佳实践是使控制器方法保持精简并将逻辑置于视图之外。因此,考虑到这一点,一种可能的方法是:

# model
class Task
  scope :drafts, where(:status => "Draft")
  scope :approved, where(:status => "Approved")
  scope :closed, where(:status => "Closed")
end

# controller
def index
  @draft_tasks = Task.drafts
  @approved_tasks = Task.approved
  @closed_tasks = Task.closed
end

这将对数据库进行 3 次查询,这可能会成为性能问题,但如果确实发生这种情况,您可以在模型级别对其进行优化(例如,通过定义类方法drafts,approved以及closed第一个调用预取所有内容的位置) . 虽然它不太优雅,所以不要过早优化。

于 2012-07-04T04:48:11.610 回答
1

在我看来,这是一个没有任何最佳实践的问题。鉴于您所说的情况(为每个显示一个表格status),我将使用以下思考过程:

  1. 当您只处理一种模型类型时,我通常会避免使用案例 A。我尽量限制数据库查询的数量
  2. 如果视图需要根据status任务显示不同的标记,我可能会使用案例 B。
  3. 如果每个的标记都相同,我通常会倾向于案例statusC。您可以为此使用group_by函数:

当页面上的信息量开始变得更大和更复杂时,您可以开始考虑从控制器中提取一些逻辑并放入另一个对象(该对象的常用术语是 apresenterdecorator)。这可以通过将其与控制器分离并保持控制器“精简”来更轻松地测试您的一些表示逻辑。但是对于您给出的情况,我会坚持使用选项 b 或 c。

于 2012-07-04T04:57:38.790 回答
1

在任务数量有限的简单情况下,我将只执行一次查询来检索它们,然后将它们分开如下:

tasks = Task.all
@draft_tasks    = tasks.select { |x| x.status == 'Draft' } 
@approved_tasks = tasks.select { |x| x.status == 'Approved' }
@closed_tasks   = tasks.select { |x| x.status == 'Closed' }

此外,根据您的要求的可弯曲性,我什至会将它们呈现在单个表格中,并带有清晰的视觉标记状态是什么(例如背景颜色或图标)。然后甚至没有理由事先分离任务(但我可以想象这会完全破坏你的 UI)。

一旦任务数量变大,以上都无效,您将需要应用分页,并且您需要显示三个不同的表格(每个状态一个)。

在这种情况下,您将需要使用@Ben 回答的三个单独的查询。

现在在 UI 方面,我不确定如何一次对三组不同的数据进行分页。因此,我将使用一个显示所有状态的表格,并提供过滤状态的选项。在这种情况下,至少用户清楚分页意味着什么。

只是我的两分钱,希望这会有所帮助。

于 2012-07-04T23:22:47.813 回答
0

选项 a) 似乎更好,因为数据库可以为您和其他东西缓存查询,所以它应该更快。

于 2012-07-04T04:43:28.783 回答