未支付订单条码按钮重复显示问题求助(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时,需明确指定取哪一条记录的条码(比如第一条、最新一条),避免显示所有关联条码。以下提供两种实现方式:
方式一:利用模型关联预加载推荐
- 先在
Payment模型中添加关联关系:
class Payment < ApplicationRecord has_many :payment_records, dependent: :destroy end
- 修改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
- 修改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
相关产品推荐
相关产品推荐

