【问题标题】:Grouping records within a view in Rails 3?在 Rails 3 的视图中对记录进行分组?
【发布时间】:2012-04-26 12:28:08
【问题描述】:

我的 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>

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

【问题讨论】:

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


    【解决方案1】:

    更简单的方法是像这样使用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

    【讨论】:

    • 这看起来比我迄今为止尝试过的任何东西都要优雅。但有一件事,遗嘱实际上称为TestDone。我已经尽一切努力让它工作,但它不会加载值。有什么提示吗?
    • @dannymcc Group_by 只会对完全相同的事物进行分组,您的 TestDone 可能包括每个实验室的不同小时、分钟和秒。我已经编辑了我的答案以使用 group_by 的完整块语法在分组操作之前预处理 TestDone。
    【解决方案2】:

    分组无法按照您想要的方式进行。首先,你不应该在你的 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 %>
    

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

    我想这就是你要找的。​​p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多