You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中如何显示最后几个无重复的PriceLog记录并消除重复显示?

解决PriceLog重复显示并展示最近记录的问题

问题根源分析

你的代码出现重复显示的核心原因有两个:

  1. 外层循环遍历的是所有PriceLog记录,而非去重的日期——如果三个产品在同一天都有价格记录,这个循环会执行3次,导致同一日期的行重复渲染3次。
  2. 每次在产品循环里重复查询数据库,不仅效率低下,还会因为多次取last导致逻辑混乱,最终出现重复内容。

解决方案

我们可以通过优化控制器数据预加载和视图逻辑来解决问题,同时实现只展示最近N个(比如2个)日期的记录。

第一步:优化控制器的new方法

修改new方法,预加载所需数据,避免N+1查询,同时获取最近的不重复日期:

def new
  @pricelog = PriceLog.new
  @products = Product.all
  # 获取最近2个不重复的日期(可根据需求修改limit的值)
  @recent_dates = PriceLog.distinct.order(price_date: :desc).limit(2).pluck(:price_date)
  # 预加载指定日期内的所有价格记录,按【产品ID+日期】分组,方便视图快速获取
  @price_logs = PriceLog.where(price_date: @recent_dates)
                        .includes(:product)
                        .group_by { |pl| [pl.product_id, pl.price_date] }
end

第二步:修改_index.html.erb视图

重写视图逻辑,基于预加载的数据渲染,避免重复和冗余查询:

<table class="table table-hover">
  <thead>
    <tr>
      <th>Date</th>
      <% @products.each do |product| %>
        <th><%= product.name %></th> <!-- 替换成你产品的显示字段,比如name -->
      <% end %>
    </tr>
  </thead>
  <tbody>
    <% @recent_dates.each do |date| %>
      <tr>
        <!-- 显示日期 -->
        <td><%= date.strftime('%d-%B-%Y') %></td>
        <!-- 遍历每个产品,显示对应日期的价格 -->
        <% @products.each do |product| %>
          <td>
            <% # 从预加载的分组数据中获取对应记录 %>
            <% log_entry = @price_logs[[product.id, date]]&.last %>
            <%= log_entry ? log_entry.price : 'No data' %> <!-- 无数据时显示提示 -->
          </td>
        <% end %>
      </tr>
    <% end %>
  </tbody>
</table>

优化后的逻辑说明

  1. 去重日期:通过distinct和limit获取最近的N个唯一日期,确保每行对应一个日期,不会重复。
  2. 预加载数据:一次性查询所需的所有PriceLog记录并分组,避免视图中重复查询数据库,提升性能。
  3. 清晰的视图结构:先按日期遍历行,再按产品遍历列,每个单元格对应一个产品在该日期的价格,逻辑清晰且无重复。

内容的提问来源于stack exchange,提问作者Bharat Mane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:36:27