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

未支付订单条码按钮重复显示问题求助(Rails实现)

未支付订单条码按钮重复显示问题解决方案

问题说明

现有payments与payment_records两张关联表,通过外键payment_id关联,每笔payment对应多条payment_records(表中包含barcode_url字段)。需求是每笔未支付订单仅显示一个对应的条码按钮,但当前循环未支付订单时,一笔订单会展示所有关联的条码按钮(多个)。

现有代码

Controller 代码

def payments
  @paid_payments = current_user.get_valid_paid_payments.order(created_at: :desc).paginate(page: params[:page], per_page: 5)
  @unpaid_payments = current_user.get_valid_unpaid_payments.order(created_at: :desc)
  payment_records = PaymentRecord.where(payment_id: @unpaid_payments.pluck(:id))
  @barcode_data = payment_records.each_with_object({}) do |record, hash|
    hash[record.payment_id] = record.barcode_url
  end
  @smartpit = current_user.smartpits.take
  @user = current_user
  render layout: 'mypage'
end

View 代码

<div class="container">
   <div class="vertical-center center-barcode">
    <% @unpaid_payments.each do |payment| %>
        <% barcode_url = @barcode_data[payment.id] %>
           <% if barcode_url.present? %>
             <a href="<%= barcode_url %>" class="btn btn-danger" target="_blank">
                 <%= t 'users.bill_detail.new_payment_method_barcode' %>
             </a>
           <% end %>
        <% end %>
    </div>
</div>

解决方案

问题核心是同一个payment对应多条payment_records时,需明确指定取哪一条记录的条码(比如第一条、最新一条),避免显示所有关联条码。以下提供两种实现方式:

方式一:利用模型关联预加载推荐

  1. 先在Payment模型中添加关联关系:
class Payment < ApplicationRecord
  has_many :payment_records, dependent: :destroy
end
  1. 修改Controller代码,预加载关联的payment_records,减少数据库查询:
def payments
  @paid_payments = current_user.get_valid_paid_payments.order(created_at: :desc).paginate(page: params[:page], per_page: 5)
  # 预加载payment_records,避免N+1查询问题
  @unpaid_payments = current_user.get_valid_unpaid_payments.order(created_at: :desc).includes(:payment_records)
  @smartpit = current_user.smartpits.take
  @user = current_user
  render layout: 'mypage'
end
  1. 修改View代码,直接取当前payment对应的第一条(或最新一条)条码:
<div class="container">
  <div class="vertical-center center-barcode">
    <% @unpaid_payments.each do |payment| %>
      <% # 取第一条关联的payment_record的条码,若要取最新的可改成 order(created_at: :desc).first %>
      <% barcode_url = payment.payment_records.first&.barcode_url %>
      <% if barcode_url.present? %>
        <a href="<%= barcode_url %>" class="btn btn-danger" target="_blank">
          <%= t 'users.bill_detail.new_payment_method_barcode' %>
        </a>
      <% end %>
    <% end %>
  </div>
</div>

方式二:保留Hash映射逻辑,分组取单条记录

修改Controller中@barcode_data的生成逻辑,按payment_id分组后仅保留单条记录的条码:

def payments
  @paid_payments = current_user.get_valid_paid_payments.order(created_at: :desc).paginate(page: params[:page], per_page: 5)
  @unpaid_payments = current_user.get_valid_unpaid_payments.order(created_at: :desc)
  # 按payment_id分组,取每组第一条记录的barcode_url
  payment_records = PaymentRecord.where(payment_id: @unpaid_payments.pluck(:id))
                                 .group_by(&:payment_id)
                                 .transform_values { |records| records.first.barcode_url }
  @barcode_data = payment_records
  @smartpit = current_user.smartpits.take
  @user = current_user
  render layout: 'mypage'
end

View代码无需修改,即可实现每笔订单仅显示一个条码按钮。

额外检查点

若仍存在重复显示,需确认get_valid_unpaid_payments方法是否返回了重复的payment记录,可添加.uniq去重:

@unpaid_payments = current_user.get_valid_unpaid_payments.order(created_at: :desc).uniq

内容的提问来源于stack exchange,提问作者ATHIRA T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:17:35