在Rails 3中对视图中的记录进行分组?

时间:2012-04-26 12:28:08

标签: ruby-on-rails-3 model group-by records

我在Rails 3应用程序中有以下代码:

显示视图(来自另一个名为animal.rb的模型)

 <% @animal.labs.each do |lab| %>
    <li>
      <%= lab.TestDone.strftime("%d %b. %Y") %> 
      <h5><%= lab.TestType %></h5>
      <h6><%= lab.TestLower %></h6> 
      <b><%= lab.TestResult %></b> 
      <h6><%= lab.TestUpper %></h6>
    </li>
<% end %>

实验室模型

belongs_to :animal
default_scope :order => "TestDone DESC", :group => "TestDone"

上述代码按日期成功分组所有结果。但是,它仅显示日期之后每个值的第一个。

例如,如果输出最初(在分组之前),如下所示:

<li>
 26 April 2012
 <h5>Glucose</h5>
 <h6>1.0</h6>
 <b>1.8</b>
 <h6>2.0</h6>
</li>

<li>
 26 April 2012
 <h5>WBC</h5>
 <h6>1.1</h6>
 <b>2.8</b>
 <h6>3.0</h6>
</li>

<li>
 26 April 2012
 <h5>ABC</h5>
 <h6>1.0</h6>
 <b>1.6</b>
 <h6>2.0</h6>
</li>

然后在分组后输出以下内容:

<li>
 26 April 2012
 <h5>Glucose</h5>
 <h6>1.0</h6>
 <b>1.8</b>
 <h6>2.0</h6>
</li>

产生这样的东西的正确方法是什么:

<li>26 April 2012</li>
<li>
  <h5>Glucose</h5>
  <h6>1.0</h6>
  <b>1.8</b>
  <h6>2.0</h6>
</li>
<li>
 <h5>WBC</h5>
 <h6>1.1</h6>
 <b>2.8</b>
 <h6>3.0</h6>
</li>
<li>
 <h5>ABC</h5>
 <h6>1.0</h6>
 <b>1.6</b>
 <h6>2.0</h6>
</li>

所以我有一个日期标题,然后下面列出了该日期的每条记录?

2 个答案:

答案 0 :(得分:3)

更简单的方法是使用group_by,如下所示:

 <% @animal.labs.group_by{|l| l.TestDone.strftime("%d %b. %Y") }.each do |testdate,labs| %>
   <li><%= testdate %></li>
   <% labs.each do |lab| %>
     <li>
       <h5><%= lab.TestType %></h5>
       <h6><%= lab.TestLower %></h6> 
       <b><%= lab.TestResult %></b> 
       <h6><%= lab.TestUpper %></h6>
     </li>
   <% end %>
 <% end %>

http://api.rubyonrails.org/classes/Enumerable.html#method-i-group_by

答案 1 :(得分:1)

分组不按您想要的方式使用。首先,我们不应该在你的default_scope中对它进行分组,但你可以在视图中或在控制器中使用一些聚合。

型号:

default_scope :order => "TestDone DESC"

查看:

<% prev = nil %>
<% @animal.labs.each do |lab| %>
    <%= "</ul></li>" if prev != nil && prev != lab.TestDone %>
    <%= "<li>"+lab.TestDone.strftime("%d %b. %Y")+"<ul>" if prev != lab.TestDone %>
      <li>
        <h5><%= lab.TestType %></h5>
        <h6><%= lab.TestLower %></h6> 
        <b><%= lab.TestResult %></b> 
        <h6><%= lab.TestUpper %></h6>
      </li>
    <% prev = lab.TestDone %>
<% end %>
<%= "</ul></li>" if prev != nil %>

不是最漂亮的解决方案,但它基于您的代码。 基本上,您需要存储最后一个元素的日期,以便将其与实际元素的日期进行比较。如果它们不同,则必须显示新日期。因为它们按日期排序,所以具有相同日期的元素彼此接近。

我认为这就是你要找的东西。